diff --git a/data/kb/components/add-component-sidebar.md b/data/kb/components/add-component-sidebar.md
deleted file mode 100644
index 617ac6446..000000000
--- a/data/kb/components/add-component-sidebar.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: How do I add a Component to the sidebar?
-slug: /knowledge-base/components/add-component-sidebar
----
-
-# How do I add a Component to the sidebar?
-
-You can add a component to [st.sidebar](/library/api-reference/layout/st.sidebar) using the `with` syntax. For example:
-
-```python
-with st.sidebar:
- my_component(greeting="hello")
-```
-
-In fact, you can add your component to _any_ [layout container](/library/api-reference/layout) (eg st.columns, st.expander), using the `with` syntax!
-
-```python
-col1, col2 = st.columns(2)
-with col2:
- my_component(greeting="hello")
-```
diff --git a/data/kb/components/component-blinking-stuttering-fix.md b/data/kb/components/component-blinking-stuttering-fix.md
deleted file mode 100644
index 825395d32..000000000
--- a/data/kb/components/component-blinking-stuttering-fix.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: My Component seems to be blinking/stuttering...how do I fix that?
-slug: /knowledge-base/components/component-blinking-stuttering-fix
----
-
-# My Component seems to be blinking/stuttering...how do I fix that?
-
-Currently, no automatic debouncing of Component updates is performed within Streamlit. The Component creator themselves can decide to rate-limit the updates they send back to Streamlit.
diff --git a/data/kb/components/how-streamlit-components-differ-base-package.md b/data/kb/components/how-streamlit-components-differ-base-package.md
deleted file mode 100644
index 06b991348..000000000
--- a/data/kb/components/how-streamlit-components-differ-base-package.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-title: How do Streamlit Components differ from functionality provided in the base Streamlit package?
-slug: /knowledge-base/components/how-streamlit-components-differ-base-package
----
-
-# How do Streamlit Components differ from functionality provided in the base Streamlit package?
-
-- Streamlit Components are wrapped up in an iframe, which gives you the ability to do whatever you want (within the iframe) using any web technology you like.
-
-- There is a strict message protocol between Components and Streamlit, which makes possible for Components to act as widgets. As Streamlit Components are wrapped in iframe, they cannot modify their parent’s DOM (a.k.a the Streamlit report), which ensures that Streamlit is always secure even with user-written components.
diff --git a/data/kb/components/index.md b/data/kb/components/index.md
deleted file mode 100644
index c0fc8e400..000000000
--- a/data/kb/components/index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: Streamlit Components
-slug: /knowledge-base/components
----
-
-# Streamlit Components
-
-Below are some selected questions we've received about Streamlit Components. If you don't find your question here, take a look on the Streamlit community forum via the [Components tag](https://discuss.streamlit.io/tag/custom-components).
-
-- [How do Streamlit Components differ from functionality provided in the base Streamlit package?](/knowledge-base/components/how-streamlit-components-differ-base-package)
-- [What types of things _*aren't possible*_ with Streamlit Components?](/knowledge-base/components/not-possibe-streamlit-components)
-- [How do I add a Component to the sidebar?](/knowledge-base/components/add-component-sidebar)
-- [My Component seems to be blinking/stuttering...how do I fix that?](/knowledge-base/components/component-blinking-stuttering-fix)
diff --git a/data/kb/components/not-possibe-streamlit-components.md b/data/kb/components/not-possibe-streamlit-components.md
deleted file mode 100644
index 1125e47d5..000000000
--- a/data/kb/components/not-possibe-streamlit-components.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: What types of things aren't possible with Streamlit Components?
-slug: /knowledge-base/components/not-possibe-streamlit-components
----
-
-# What types of things aren't possible with Streamlit Components?
-
-Because each Streamlit Component gets mounted into its own sandboxed iframe, this implies a few limitations on what is possible with Components:
-
-- **Can't communicate with other Components**: Components can’t contain (or otherwise communicate with) other components, so Components cannot be used to build something like `grid_layout`
-- **Can't modify CSS**: A Component can’t modify the CSS that the rest of the Streamlit app uses, so you can't create something like `dark_mode`
-- **Can't add/remove elements**: A Component can’t add or remove other elements of a Streamlit app, so you couldn't make something like `remove_streamlit_app_menu`
diff --git a/data/kb/dependencies/index.md b/data/kb/dependencies/index.md
deleted file mode 100644
index 96edc994f..000000000
--- a/data/kb/dependencies/index.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: Installing dependencies
-slug: /knowledge-base/dependencies
----
-
-# Installing dependencies
-
-- [ModuleNotFoundError: No module named](/knowledge-base/dependencies/module-not-found-error)
-- [ImportError: libGL.so.1: cannot open shared object file: No such file or directory](/knowledge-base/dependencies/libgl)
-- [ERROR: No matching distribution found for](/knowledge-base/dependencies/no-matching-distribution)
-- [How to install a package not on PyPI/Conda but available on GitHub](/knowledge-base/dependencies/install-package-not-pypi-conda-available-github)
-- [Install the Snowflake Connector for Python on Streamlit Community Cloud](/knowledge-base/dependencies/snowflake-connector-python-streamlit-cloud)
diff --git a/data/kb/dependencies/install-package-pypi-github.md b/data/kb/dependencies/install-package-pypi-github.md
deleted file mode 100644
index fc57f067b..000000000
--- a/data/kb/dependencies/install-package-pypi-github.md
+++ /dev/null
@@ -1,58 +0,0 @@
----
-title: How to install a package not on PyPI/Conda but available on GitHub
-slug: /knowledge-base/dependencies/install-package-not-pypi-conda-available-github
----
-
-# How to install a package not on PyPI/Conda but available on GitHub
-
-## Overview
-
-Are you trying to deploy your app to [Streamlit Community Cloud](/streamlit-community-cloud), but don't know how to specify a [Python dependency](/streamlit-community-cloud/deploy-your-app/app-dependencies#add-python-dependencies) in your requirements file that is available on a public GitHub repo but not any package index like PyPI or Conda? If so, continue reading to find out how!
-
-Let's suppose you want to install `SomePackage` and its Python dependencies from GitHub, a hosting service for the popular version control system (VCS) Git. And suppose `SomePackage` is found at the the following URL: `https://github.com/SomePackage.git`.
-
-pip (via `requirements.txt`) [supports](https://pip.pypa.io/en/stable/topics/vcs-support/) installing from GitHub. This support requires a working executable to be available (for Git). It is used through a URL prefix: `git+`.
-
-## Specify the GitHub web URL
-
-To install `SomePackage`, innclude the following in your `requirements.txt` file:
-
-```bash
-git+https://github.com/SomePackage#egg=SomePackage
-```
-
-You can even specify a "git ref" such as branch name, a commit hash or a tag name, as shown in the examples below.
-
-## Specify a Git branch name
-
-Install `SomePackage` by specifying a branch name such as `main`, `master`, `develop`, etc, in `requirements.txt`:
-
-```bash
-git+https://github.com/SomePackage.git@main#egg=SomePackage
-```
-
-## Specify a commit hash
-
-Install `SomePackage` by specifying a commit hash in `requirements.txt`:
-
-```bash
-git+https://github.com/SomePackage.git@eb40b4ff6f7c5c1e4366cgfg0671291bge918#egg=SomePackage
-```
-
-## Specify a tag
-
-Install `SomePackage` by specifying a tag in `requirements.txt`:
-
-```bash
-git+https://github.com/SomePackage.git@v1.1.0#egg=SomePackage
-```
-
-## Limitations
-
-It is currently **not possible** to install private packages from private GitHub repos using the URI form:
-
-```bash
-git+https://{token}@github.com/user/project.git@{version}
-```
-
-where `version` is a tag, a branch, or a commit. And `token` is a personal access token with read only permissions. Streamlit Community Cloud only supports installing public packages from public GitHub repos.
diff --git a/data/kb/dependencies/libgl.md b/data/kb/dependencies/libgl.md
deleted file mode 100644
index d17879eb5..000000000
--- a/data/kb/dependencies/libgl.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: ImportError libGL.so.1 cannot open shared object file No such file or directory
-slug: /knowledge-base/dependencies/libgl
----
-
-# ImportError libGL.so.1 cannot open shared object file No such file or directory
-
-## Problem
-
-You receive the error `ImportError libGL.so.1 cannot open shared object file No such file or directory` when using OpenCV in your app deployed on [Streamlit Community Cloud](https://streamlit.io/cloud).
-
-## Solution
-
-If you use OpenCV in your app, include `opencv-python-headless` in your requirements file on Streamlit Community Cloud in place of `opencv_contrib_python` and `opencv-python`.
-
-If `opencv-python` is a _required_ (non-optional) dependency of your app or a dependency of a library used in your app, the above solution is not applicable. Instead, you can use the following solution:
-
-Create a `packages.txt` file in your repo with the following line to install the [apt-get dependency](/streamlit-community-cloud/deploy-your-app/app-dependencies#apt-get-dependencies) `libgl`:
-
-```
-libgl1
-```
diff --git a/data/kb/dependencies/module-not-found-error.md b/data/kb/dependencies/module-not-found-error.md
deleted file mode 100644
index a39c62245..000000000
--- a/data/kb/dependencies/module-not-found-error.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: ModuleNotFoundError No module named
-slug: /knowledge-base/dependencies/module-not-found-error
----
-
-# ModuleNotFoundError: No module named
-
-## Problem
-
-You receive the error `ModuleNotFoundError: No module named` when you deploy an app on [Streamlit Community Cloud](https://streamlit.io/cloud).
-
-## Solution
-
-This error occurs when you import a module on Streamlit Community Cloud that isn’t included in your requirements file. Any external [Python dependencies](/streamlit-community-cloud/deploy-your-app/app-dependencies#add-python-dependencies) that are not distributed with a [standard Python installation](https://docs.python.org/3/py-modindex.html) should be included in your requirements file.
-
-E.g. You will see `ModuleNotFoundError: No module named 'sklearn'` if you don’t include `scikit-learn` in your requirements file and `import sklearn` in your app.
-
-Related forum posts:
-
-- https://discuss.streamlit.io/t/getting-error-modulenotfounderror-no-module-named-beautifulsoup/9126
-- https://discuss.streamlit.io/t/modulenotfounderror-no-module-named-vega-datasets/16354
diff --git a/data/kb/dependencies/no-matching-distribution.md b/data/kb/dependencies/no-matching-distribution.md
deleted file mode 100644
index cc63fcafe..000000000
--- a/data/kb/dependencies/no-matching-distribution.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: ERROR No matching distribution found for
-slug: /knowledge-base/dependencies/no-matching-distribution
----
-
-# ERROR: No matching distribution found for
-
-## Problem
-
-You receive the error `ERROR: No matching distribution found for` when you deploy an app on [Streamlit Community Cloud](https://streamlit.io/cloud).
-
-## Solution
-
-This error occurs when you deploy an app on Streamlit Community Cloud and have one or more of the following issues with your [Python dependencies](/streamlit-community-cloud/deploy-your-app/app-dependencies#add-python-dependencies) in your requirements file:
-
-1. The package is part of the [Python Standard Library](https://docs.python.org/3/py-modindex.html). E.g. You will see **`ERROR: No matching distribution found for base64`** if you include [`base64`](https://docs.python.org/3/library/base64.html) in your requirements file, as it is part of the Python Standard Library. The solution is to not include the package in your requirements file. Only include packages in your requirements file that are not distributed with a standard Python installation.
-2. The package name in your requirements file is misspelled. Double-check the package name before including it in your requirements file.
-3. The package does not support the operating system on which your Streamlit app is running. E.g. You see **`ERROR: No matching distribution found for pywin32`** while deploying to Streamlit Community Cloud. The `pywin32` module provides access to many of the Windows APIs from Python. Apps deployed to Streamlit Community Cloud are executed in a Linux environment. As such, `pywin32` fails to install on non-Windows systems, including on Streamlit Community Cloud. The solution is to either exclude `pywin32` from your requirements file, or deploy your app on a cloud service offering Windows machines.
-
-Related forum posts:
-
-- https://discuss.streamlit.io/t/error-no-matching-distribution-found-for-base64/15758
-- https://discuss.streamlit.io/t/error-could-not-find-a-version-that-satisfies-the-requirement-pywin32-301-from-versions-none/15343/2
diff --git a/data/kb/dependencies/snowflake-connector-python.md b/data/kb/dependencies/snowflake-connector-python.md
deleted file mode 100644
index 1157c63d4..000000000
--- a/data/kb/dependencies/snowflake-connector-python.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: Install the Snowflake Connector for Python on Streamlit Community Cloud
-slug: /knowledge-base/dependencies/snowflake-connector-python-streamlit-cloud
----
-
-# Install the Snowflake Connector for Python on Streamlit Community Cloud
-
-The Snowflake Connector for Python is available on [PyPI](https://pypi.org/project/snowflake-connector-python/) and the installation instructions are found in the [Snowflake documentation](https://docs.snowflake.com/en/user-guide/python-connector-install.html#step-1-install-the-connector). When installing the connector, Snowflake recommends installing specific versions of its dependent libraries. The steps below will help you install the connector and its dependencies on Streamlit Community Cloud:
-
-1. Determine the version of the Snowflake Connector for Python you want to install.
-2. Determine the version of Python you want to use on Streamlit Community Cloud.
-3. To install the connector and the dependent libraries, select the [requirements file](https://github.com/snowflakedb/snowflake-connector-python/tree/main/tested_requirements) for that version of the connector and Python.
-4. Add the raw GitHub URL of the requirements file to your `requirements.txt` file and prepend `-r` to the line.
- For example, if you want to install version `2.7.9` of the connector on Python 3.9, add the following line to your `requirements.txt` file:
-
- ```bash
- -r https://raw.githubusercontent.com/snowflakedb/snowflake-connector-python/v2.7.9/tested_requirements/requirements_39.reqs
- ```
-
-5. On Streamlit Community Cloud, select the appropriate version of Python for your app by clicking "Advanced settings" before you deploy the app:
-
-
-
-
-That's it! You're ready to use the Snowflake Connector for Python on Streamlit Community Cloud. ❄️🎈
-
-
-
-As the Snowflake dependencies [requirements files](https://github.com/snowflakedb/snowflake-connector-python/tree/main/tested_requirements) (`.reqs`) contain the pinned version of the connector, there is **no need** add a separate entry for the connector to requirements.txt.
-
-
-
-Additional resources:
-
-- [Installing the Python Connector](https://docs.snowflake.com/en/user-guide/python-connector-install.html#step-1-install-the-connector)
-- [Unable to Deploy streamlit app with snowflake-connector-python](https://discuss.streamlit.io/t/unable-to-deploy-streamlit-app-with-snowflake-connector-python/27318)
-- [Prerequisite Python packages for the Snowflake Connector](https://docs.snowflake.com/en/user-guide/python-connector-install.html#label-python-connector-prerequisites-python-packages)
diff --git a/data/kb/deployments/authentication-without-sso.md b/data/kb/deployments/authentication-without-sso.md
deleted file mode 100644
index 98bcdcf87..000000000
--- a/data/kb/deployments/authentication-without-sso.md
+++ /dev/null
@@ -1,172 +0,0 @@
----
-title: Authentication without SSO
-slug: /knowledge-base/deploy/authentication-without-sso
----
-
-# Authentication without SSO
-
-## Introduction
-
-Want to secure your Streamlit app with passwords, but cannot implement single sign-on? We got you covered! This guide shows you two simple techniques for adding basic authentication to your Streamlit app, using [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-While this technique adds some level of security, it is **NOT** comparable to proper authentication with an SSO provider.
-
-
-
-## Option 1: One global password for all users
-
-This is the easiest option! Your app will ask for a password that's shared between all users. It will be stored in the app secrets using [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management). If you want to change this password or revoke a user's access, you will need to change it for everyone. If you want to have one password per user instead, jump to [Option 2 below](/knowledge-base/deploy/authentication-without-sso#option-2-individual-password-for-each-user).
-
-### Step 1: Add the password to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root dir. Create this file if it doesn't exist yet and add your password to it as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-password = "streamlit123"
-```
-
-
-
-Be sure to add this file to your `.gitignore` so you don't commit your secrets!
-
-
-
-### Step 2: Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-### Step 3: Ask for the password in your Streamlit app
-
-Copy the code below to your Streamlit app, insert your normal app code in the `if` statement at the bottom, and run it:
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-def check_password():
- """Returns `True` if the user had the correct password."""
-
- def password_entered():
- """Checks whether a password entered by the user is correct."""
- if st.session_state["password"] == st.secrets["password"]:
- st.session_state["password_correct"] = True
- del st.session_state["password"] # don't store password
- else:
- st.session_state["password_correct"] = False
-
- if "password_correct" not in st.session_state:
- # First run, show input for password.
- st.text_input(
- "Password", type="password", on_change=password_entered, key="password"
- )
- return False
- elif not st.session_state["password_correct"]:
- # Password not correct, show input + error.
- st.text_input(
- "Password", type="password", on_change=password_entered, key="password"
- )
- st.error("😕 Password incorrect")
- return False
- else:
- # Password correct.
- return True
-
-if check_password():
- st.write("Here goes your normal Streamlit app...")
- st.button("Click me")
-```
-
-If everything worked out, your app should look like this:
-
-
-
-## Option 2: Individual password for each user
-
-This option allows you to set a username and password for each user of your app. Like in [Option 1](#option-1-one-global-password-for-all-users), both values will be stored in the app secrets using [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-### Step 1: Add usernames & passwords to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root dir. Create this file if it doesn't exist yet and add the usernames & password to it as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[passwords]
-# Follow the rule: username = "password"
-alice_foo = "streamlit123"
-bob_bar = "mycrazypw"
-```
-
-
-
-Be sure to add this file to your `.gitignore` so you don't commit your secrets!
-
-
-
-Alternatively, you could set up and manage usernames & passwords via a spreadsheet or database. To use secrets to securely connect to Google Sheets, AWS, and other data providers, read our tutorials on how to [Connect Streamlit to data sources](/knowledge-base/tutorials/databases).
-
-### Step 2: Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-### Step 3: Ask for username & password in your Streamlit app
-
-Copy the code below to your Streamlit app, insert your normal app code in the `if` statement at the bottom, and run it:
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-def check_password():
- """Returns `True` if the user had a correct password."""
-
- def password_entered():
- """Checks whether a password entered by the user is correct."""
- if (
- st.session_state["username"] in st.secrets["passwords"]
- and st.session_state["password"]
- == st.secrets["passwords"][st.session_state["username"]]
- ):
- st.session_state["password_correct"] = True
- del st.session_state["password"] # don't store username + password
- del st.session_state["username"]
- else:
- st.session_state["password_correct"] = False
-
- if "password_correct" not in st.session_state:
- # First run, show inputs for username + password.
- st.text_input("Username", on_change=password_entered, key="username")
- st.text_input(
- "Password", type="password", on_change=password_entered, key="password"
- )
- return False
- elif not st.session_state["password_correct"]:
- # Password not correct, show input + error.
- st.text_input("Username", on_change=password_entered, key="username")
- st.text_input(
- "Password", type="password", on_change=password_entered, key="password"
- )
- st.error("😕 User not known or password incorrect")
- return False
- else:
- # Password correct.
- return True
-
-if check_password():
- st.write("Here goes your normal Streamlit app...")
- st.button("Click me")
-```
-
-If everything worked out, your app should look like this:
-
-
diff --git a/data/kb/deployments/custom-subdomains.md b/data/kb/deployments/custom-subdomains.md
deleted file mode 100644
index eaba4983c..000000000
--- a/data/kb/deployments/custom-subdomains.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-title: Custom subdomains
-slug: /knowledge-base/deploy/custom-subdomains
----
-
-# Custom subdomains
-
-Once you've [deployed your app](/streamlit-community-cloud/deploy-your-app) on Community Cloud, it's given an automatically generated subdomain that follows a structure based on your GitHub repo. This subdomain is unique to your app and can be used to share your app with others. However, the default subdomain is not always the most memorable or easy to share. E.g. the following is a bit of a mouthful!
-
-`https://streamlit-demo-self-driving-streamlit-app-8jya0g.streamlit.app`
-
-You can instead set up a custom subdomain to make your app easier to share. You can customize your subdomain to reflect your app content, personal branding, or whatever you’d like. The URL will appear as:
-
-```
-.streamlit.app
-```
-
-To customize your app subdomain from your [workspace](/streamlit-community-cloud/manage-your-app#manage-your-app-from-your-workspace):
-
-1. Click the "︙" overflow menu to the app's right and select "**Settings**".
-
- 
-
-2. View the "**General**" tab in the App settings modal. Your app's unique subdomain will appear here.
- 
-
-3. Pick a custom subdomain between 6 and 63 characters in length for your app's URL and hit "**Save**".
- 
-
-It's that simple! You can then access your app by visiting your custom subdomain URL 🎉.
-
-If a custom subdomain is not available (e.g. because it's already taken), you'll see an error message like this:
-
-
diff --git a/data/kb/deployments/deploy-multiple-streamlit-apps-different-subdomains.md b/data/kb/deployments/deploy-multiple-streamlit-apps-different-subdomains.md
deleted file mode 100644
index d56596829..000000000
--- a/data/kb/deployments/deploy-multiple-streamlit-apps-different-subdomains.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: How can I deploy multiple Streamlit apps on different subdomains?
-slug: /knowledge-base/deploy/deploy-multiple-streamlit-apps-different-subdomains
----
-
-# How can I deploy multiple Streamlit apps on different subdomains?
-
-## Problem
-
-You want to deploy multiple Streamlit apps on different subdomains.
-
-## Solution
-
-Like running your Streamlit app on more common ports such as 80, subdomains are handled by a web server like Apache or Nginx:
-
-- Set up a web server on a machine with a public IP address, then use a DNS server to point all desired subdomains to your webserver's IP address
-
-- Configure your web server to route requests for each subdomain to the different ports that your Streamlit apps are running on
-
-For example, let’s say you had two Streamlit apps called `Calvin` and `Hobbes`. App `Calvin` is running on port **8501**. You set up app `Hobbes` to run on port **8502**. Your webserver would then be set up to "listen" for requests on subdomains `calvin.somedomain.com` and `hobbes.subdomain.com`, and route requests to port **8501** and **8502**, respectively.
-
-Check out these two tutorials for Apache2 and Nginx that deal with setting up a webserver to redirect subdomains to different ports:
-
-- [Apache2 subdomains](https://stackoverflow.com/questions/8541182/apache-redirect-to-another-port)
-- [NGinx subdomains](https://gist.github.com/soheilhy/8b94347ff8336d971ad0)
diff --git a/data/kb/deployments/deploy-streamlit-domain-port-80.md b/data/kb/deployments/deploy-streamlit-domain-port-80.md
deleted file mode 100644
index 1cb10d9a2..000000000
--- a/data/kb/deployments/deploy-streamlit-domain-port-80.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: How do I deploy Streamlit on a domain so it appears to run on a regular port (i.e. port 80)?
-slug: /knowledge-base/deploy/deploy-streamlit-domain-port-80
----
-
-# How do I deploy Streamlit on a domain so it appears to run on a regular port (i.e. port 80)?
-
-## Problem
-
-You want to deploy a Streamlit app on a domain so it appears to run on port 80.
-
-## Solution
-
-- You should use a **reverse proxy** to forward requests from a webserver like [Apache](https://httpd.apache.org/) or [Nginx](https://www.nginx.com/) to the port where your Streamlit app is running. You can accomplish this in several different ways. The simplest way is to [forward all requests sent to your domain](https://discuss.streamlit.io/t/permission-denied-in-ec2-port-80/798/3) so that your Streamlit app appears as the content of your website.
-
-- Another approach is to configure your webserver to forward requests to designated subfolders (e.g. _http://awesomestuff.net/streamlitapp_) to different Streamlit apps on the same domain, as in this [example config for Nginx](https://discuss.streamlit.io/t/how-to-use-streamlit-with-nginx/378/7) submitted by a Streamlit community member.
-
-Related forum posts:
-
-- https://discuss.streamlit.io/t/permission-denied-in-ec2-port-80/798/3
-- https://discuss.streamlit.io/t/how-to-use-streamlit-with-nginx/378/7
diff --git a/data/kb/deployments/deploy-streamlit-heroku-aws-google-cloud.md b/data/kb/deployments/deploy-streamlit-heroku-aws-google-cloud.md
deleted file mode 100644
index 9af605495..000000000
--- a/data/kb/deployments/deploy-streamlit-heroku-aws-google-cloud.md
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: How do I deploy Streamlit on Heroku, AWS, Google Cloud, etc...?
-slug: /knowledge-base/deploy/deploy-streamlit-heroku-aws-google-cloud
----
-
-# How do I deploy Streamlit on Heroku, AWS, Google Cloud, etc...?
-
-## Problem
-
-You want to deploy your Streamlit app on a cloud service other than [Streamlit Community Cloud](https://streamlit.io/cloud).
-
-## Solution
-
-
-
-
-
-
-
Docker
-
-
-
-
-
-
-
-
Kubernetes
-
-
-
-
-While we work on official Streamlit deployment guides for other hosting providers, here are some user-submitted tutorials for different cloud services:
-
-- [How to deploy Streamlit apps to Google App Engine](https://dev.to/whitphx/how-to-deploy-streamlit-apps-to-google-app-engine-407o), by [Yuichiro Tachibana (Tsuchiya)](https://discuss.streamlit.io/u/whitphx/summary)
-- [How to Deploy Streamlit to a Free Amazon EC2 instance](https://towardsdatascience.com/how-to-deploy-a-streamlit-app-using-an-amazon-free-ec2-instance-416a41f69dc3), by Rahul Agarwal
-- [Host Streamlit on Heroku](https://towardsdatascience.com/quickly-build-and-deploy-an-application-with-streamlit-988ca08c7e83), by Maarten Grootendorst
-- [Host Streamlit on Azure](https://towardsdatascience.com/deploying-a-streamlit-web-app-with-azure-app-service-1f09a2159743), by Richard Peterson
-- [Host Streamlit on 21YunBox](https://www.21yunbox.com/docs/#/deploy-streamlit), by Toby Lei
-
-You can find guides for other hosting providers on our [community-supported deployment wiki](https://discuss.streamlit.io/t/streamlit-deployment-guide-wiki/5099).
diff --git a/data/kb/deployments/does-streamlit-support-wsgi-protocol.md b/data/kb/deployments/does-streamlit-support-wsgi-protocol.md
deleted file mode 100644
index b17ec6519..000000000
--- a/data/kb/deployments/does-streamlit-support-wsgi-protocol.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: Does Streamlit support the WSGI Protocol? (aka Can I deploy Streamlit with gunicorn?)
-slug: /knowledge-base/deploy/does-streamlit-support-wsgi-protocol
----
-
-# Does Streamlit support the WSGI Protocol? (aka Can I deploy Streamlit with gunicorn?)
-
-## Problem
-
-You're not sure whether your Streamlit app can be deployed with gunicorn.
-
-## Solution
-
-Streamlit does not support the WSGI protocol at this time, so deploying Streamlit with (for example) gunicorn is not currently possible. Check out this [forum thread regarding deploying Streamlit in a gunicorn-like manner](https://discuss.streamlit.io/t/how-do-i-set-the-server-to-0-0-0-0-for-deployment-using-docker/216) to see how other users have accomplished this.
diff --git a/data/kb/deployments/how-to-delete-account.md b/data/kb/deployments/how-to-delete-account.md
deleted file mode 100644
index b997b4494..000000000
--- a/data/kb/deployments/how-to-delete-account.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: How to delete your Streamlit Community Cloud account
-slug: /knowledge-base/deploy/how-to-delete-your-streamlit-community-cloud-account
----
-
-# How to delete your Streamlit Community Cloud account
-
-Deleting your Streamlit Community Cloud account is just as easy as creating it via the Settings tab. When you delete your account, your information, account, and all your hosted apps are deleted as well.
-
-
-
-Deleting your account is permanent and cannot be undone. Make sure you really want to delete your account and all hosted apps before proceeding.
-
-
-
-## How to delete your account
-
-Follow these steps to delete your account:
-
-1. Make sure you are logged in to Streamlit Community Cloud: [https://share.streamlit.io/](https://share.streamlit.io/).
-2. Click 'Settings' in the top right corner of the page to go to the Settings dashboard. In the 'Account' section, click 'Delete account':
-
-3. In the 'Delete account?' modal that appears, you will be asked to confirm that you want to delete your account by typing:
-
- ```
- delete
- ```
-
- Type in `delete ` followed by your email address and click 'Delete account forever':
-
-
-
-4. You will then be logged out and your account, information, and apps will be permanently deleted.
-
-5. Upon deletion, you're shown a confirmation message that your account has been deleted, after which you will be redirected to the Streamlit Community Cloud homepage.
-
-
-It's that simple! If you have any questions or run into issues deleting your account, please reach out to us on the [Forum](https://discuss.streamlit.io/c/community-cloud/13). We're happy to help! 🎈
diff --git a/data/kb/deployments/how-to-submit-a-support-case-for-streamlit-community-cloud.md b/data/kb/deployments/how-to-submit-a-support-case-for-streamlit-community-cloud.md
deleted file mode 100644
index 19b41250e..000000000
--- a/data/kb/deployments/how-to-submit-a-support-case-for-streamlit-community-cloud.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: How to submit a support case for Streamlit Community Cloud
-slug: /knowledge-base/deploy/how-to-submit-a-support-case-for-streamlit-community-cloud
----
-
-# How to submit a support case for Streamlit Community Cloud
-
-This article describes the steps to submit a support request to Snowflake for Streamlit Community Cloud.
-
-
-
-For Snowflake customers, a support case can be submitted via [the support portal on Snowsight](https://community.snowflake.com/s/article/How-To-Submit-a-Support-Case-in-Snowflake-Lodge#Option1).
-
-
-
-1. Navigate to [https://community.snowflake.com/s/](https://community.snowflake.com/s/) in your browser.
-2. Ensure you are registered.
-
- a. _If you are already a registered user_, enter your Snowflake Community username and password into the login form. Click **LOG IN**.
-
- b. _If you are not a registered user_, click "**Not a member?**". Complete the form on the next screen and follow the instructions to reset your password. Return to the original "SUBMIT A CASE" page and log in to your account.
-
- 
-
-3. Scroll down to the first main section of the page (past the search bar) and locate the **Support** dropdown menu. Select the "**SUBMIT A CASE**" link.
-4. Select the option "**I am a Streamlit Community Cloud User**"
- 
-
-5. Hit the button "Next" to open the case description page.
-6. Please fill out your request and submit the support case.
-7. You should receive a confirmation email with the case number.
-
-A Snowflake Support engineer will follow up directly with the next steps to resolve your case. All communication will be through email.
diff --git a/data/kb/deployments/how-to-update-account-admin-settings-on-streamlit-community-cloud.md b/data/kb/deployments/how-to-update-account-admin-settings-on-streamlit-community-cloud.md
deleted file mode 100644
index eedcab587..000000000
--- a/data/kb/deployments/how-to-update-account-admin-settings-on-streamlit-community-cloud.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: How to update account admin settings on Streamlit Community Cloud?
-slug: /knowledge-base/deploy/how-to-update-account-admin-settings-on-streamlit-community-cloud
----
-
-# How to update account admin settings on Streamlit Community Cloud?
-
-Since retiring our paid Cloud plans in mid-2022, Streamlit Community Cloud no longer has account admins. Instead, app permissions are derived from GitHiub. In other words, to edit an app, you’ll need permission to make changes to the app’s GitHub repository and the changes will happen in GitHub.
diff --git a/data/kb/deployments/huh-this-is-isnt-supposed-to-happen-message-after-trying-to-log-in.md b/data/kb/deployments/huh-this-is-isnt-supposed-to-happen-message-after-trying-to-log-in.md
deleted file mode 100644
index 441883b1e..000000000
--- a/data/kb/deployments/huh-this-is-isnt-supposed-to-happen-message-after-trying-to-log-in.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: Huh. This is isn't supposed to happen message after trying to log in
-slug: /knowledge-base/deploy/huh-this-isnt-supposed-to-happen-message-after-trying-to-log-in
----
-
-# Huh. This is isn't supposed to happen message after trying to log in
-
-This article helps to resolve the login issue caused by email mismatching between the GitHub and the Streamlit Community Cloud.
-
-## Problem
-
-You see the following message after signing in to your Streamlit Community Cloud account:
-
-
-
-This message usually indicates that our system has linked your GitHub username with an email address other than the email address you're currently logged in with.
-
-## Solution
-
-No worries – all you have to do is:
-
-1. Log out of Streamlit Community Cloud completely (via both your email and GitHub accounts).
-2. Log in first with your email account (you can do so via either ["Continue with Google"](/streamlit-community-cloud/manage-your-account/sign-in-sign-out#sign-in-with-google) or ["Continue with email"](/knowledge-base/deploy/sign-in-without-sso)).
-3. Log in with your [GitHub account](/streamlit-community-cloud/manage-your-account/sign-in-sign-out#sign-in-with-email).
diff --git a/data/kb/deployments/huh-this-isnt-supposed-to-happen-no-valid-sso-connection-for-domain.md b/data/kb/deployments/huh-this-isnt-supposed-to-happen-no-valid-sso-connection-for-domain.md
deleted file mode 100644
index cf9e21775..000000000
--- a/data/kb/deployments/huh-this-isnt-supposed-to-happen-no-valid-sso-connection-for-domain.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: Huh. This isn't supposed to happen. No valid SSO connection for domain
-slug: /knowledge-base/deploy/huh-this-isnt-supposed-to-happen-no-valid-sso-connection-for-domain
----
-
-# Huh. This isn't supposed to happen. No valid SSO connection for domain
-
-This KB helps you resolve the No valid SSO connection error while login to Streamlit Community Cloud with SSO.
-
-## Problem
-
-You have got the following screen when trying to login to your Streamlit Community Cloud account with SSO(SAML authentication):
-
-
-
-This message means that you’ve logged in with both GitHub and Google in the past, but now you’re trying to log in with only GitHub.
-
-## Solution
-
-You can resolve the error by just logging in with both GitHub and Google and then, if you’d like to unlink your Google account from Streamlit Community Cloud, you can then log out via only Google.
diff --git a/data/kb/deployments/increase-upload-limit-cloud.md b/data/kb/deployments/increase-upload-limit-cloud.md
deleted file mode 100644
index bf0ea4737..000000000
--- a/data/kb/deployments/increase-upload-limit-cloud.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: How do I increase the upload limit of st.file_uploader on Streamlit Community Cloud?
-slug: /knowledge-base/deploy/increase-file-uploader-limit-streamlit-cloud
----
-
-# How do I increase the upload limit of st.file_uploader on Streamlit Community Cloud?
-
-## Overview
-
-By default, files uploaded using [`st.file_uploader()`](/library/api-reference/widgets/st.file_uploader) are limited to 200MB. You can configure this using the `server.maxUploadSize` config option.
-
-Streamlit provides [four different ways to set configuration options](/library/advanced-features/configuration#set-configuration-options):
-
-1. In a **global config file** at `~/.streamlit/config.toml` for macOS/Linux or `%userprofile%/.streamlit/config.toml` for Windows:
- ```toml
- [server]
- maxUploadSize = 200
- ```
-2. In a **per-project config file** at `$CWD/.streamlit/config.toml`, where `$CWD` is the folder you're running Streamlit from.
-3. Through `STREAMLIT_*` **environment variables**, such as:
- ```bash
- export STREAMLIT_SERVER_MAX_UPLOAD_SIZE=200
- ```
-4. As **flags on the command line** when running `streamlit run`:
- ```bash
- streamlit run your_script.py --server.maxUploadSize 200
- ```
-
-Which of the four options should you choose for an app deployed to [Streamlit Community Cloud](/streamlit-community-cloud)? 🤔
-
-## Solution
-
-When deploying your app to Streamlit Community Cloud, you should **use option 1**. Namely, set the `maxUploadSize` config option in a global config file (`.streamlit/config.toml`) uploaded to your app's GitHub repo. 🎈
-
-For example, to increase the upload limit to 400MB, upload a `.streamlit/config.toml` file containing the following lines to your app's GitHub repo:
-
-```toml
-[server]
-maxUploadSize = 400
-```
-
-## Relevant resources
-
-- [Streamlit drag and drop capping at 200MB, need workaround](https://discuss.streamlit.io/t/streamlit-drag-and-drop-capping-at-200mb-need-workaround/19803/2)
-- [File uploader widget API](/library/api-reference/widgets/st.file_uploader)
-- [How to set Streamlit configuration options](/library/advanced-features/configuration#set-configuration-options)
diff --git a/data/kb/deployments/index.md b/data/kb/deployments/index.md
deleted file mode 100644
index dbd70d589..000000000
--- a/data/kb/deployments/index.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: Deployment Issues
-slug: /knowledge-base/deploy
----
-
-# Deployment-related questions and errors
-
-- [How do I deploy Streamlit on a domain so it appears to run on a regular port (i.e. port 80)?](/knowledge-base/deploy/deploy-streamlit-domain-port-80)
-- [How can I deploy multiple Streamlit apps on different subdomains?](/knowledge-base/deploy/deploy-multiple-streamlit-apps-different-subdomains)
-- [How do I deploy Streamlit on Heroku, AWS, Google Cloud, etc...?](/knowledge-base/deploy/deploy-streamlit-heroku-aws-google-cloud)
-- [Invoking a Python subprocess in a deployed Streamlit app](/knowledge-base/deploy/invoking-python-subprocess-deployed-streamlit-app)
-- [Does Streamlit support the WSGI Protocol? (aka Can I deploy Streamlit with gunicorn?)](/knowledge-base/deploy/does-streamlit-support-wsgi-protocol)
-- [Argh. This app has gone over its resource limits.](/knowledge-base/deploy/resource-limits)
-- [App is not loading when running remotely](/knowledge-base/deploy/remote-start)
-- [Authentication without SSO](/knowledge-base/deploy/authentication-without-sso)
-- [I don't have GitHub or GSuite. How do I sign in to Streamlit Community Cloud?](/knowledge-base/deploy/sign-in-without-sso)
-- [Upgrade the Streamlit version of your app on Streamlit Community Cloud](/knowledge-base/deploy/upgrade-streamlit-version-on-streamlit-cloud)
-- [Organizing your apps with workspaces on Streamlit Community Cloud](/knowledge-base/deploy/organizing-apps-workspaces-streamlit-cloud)
-- [How do I increase the upload limit of `st.file_uploader` on Streamlit Community Cloud?](/knowledge-base/deploy/increase-file-uploader-limit-streamlit-cloud)
-- [How do I customize my app's subdomain?](/knowledge-base/deploy/custom-subdomains)
-- [How to update account admin settings on Streamlit Community Cloud?](/knowledge-base/deploy/how-to-update-account-admin-settings-on-streamlit-community-cloud)
-- [Unable to edit or delete apps in Streamlit Community Cloud after modifying GitHub username](/knowledge-base/deploy/unable-to-edit-or-delete-apps-in-streamlit-community-cloud-after-modifying-github-username)
-- [Huh. This is isn't supposed to happen message after trying to log in](/knowledge-base/deploy/huh-this-isnt-supposed-to-happen-message-after-trying-to-log-in)
-- [Huh. This isn't supposed to happen. No valid SSO connection for domain](/knowledge-base/deploy/huh-this-isnt-supposed-to-happen-no-valid-sso-connection-for-domain)
-- [View-only access to app after changing GitHub username or repository name](/knowledge-base/deploy/view-only-access-to-app-after-changing-github-username-or-repository-name)
-- [Login attempt to Streamlit Community Cloud fails with error 403](/knowledge-base/deploy/login-attempt-to-streamlit-community-cloud-fails-with-error-403)
-- [How to submit a support case for Streamlit Community Cloud](/knowledge-base/deploy/how-to-submit-a-support-case-for-streamlit-community-cloud)
-- [How to delete your Streamlit Community Cloud account](/knowledge-base/deploy/how-to-delete-your-streamlit-community-cloud-account)
diff --git a/data/kb/deployments/invoking-python-subprocess-deployed-streamlit-app.md b/data/kb/deployments/invoking-python-subprocess-deployed-streamlit-app.md
deleted file mode 100644
index 68c6773ee..000000000
--- a/data/kb/deployments/invoking-python-subprocess-deployed-streamlit-app.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: Invoking a Python subprocess in a deployed Streamlit app
-slug: /knowledge-base/deploy/invoking-python-subprocess-deployed-streamlit-app
----
-
-# Invoking a Python subprocess in a deployed Streamlit app
-
-## Problem
-
-Let's suppose you want to invoke a subprocess to run a Python script `script.py` in your deployed Streamlit app `streamlit_app.py`. For example, the machine learning library [Ludwig](https://ludwig-ai.github.io/ludwig-docs/) is run using a command-line interface, or maybe you want to run a bash script or similar type of process from Python.
-
-You have tried the following, but run into dependency issues for `script.py`, even though you have specified your Python dependencies in a requirements file:
-
-```python
-# streamlit_app.py
-import streamlit as st
-import subprocess
-
-subprocess.run(["python", "script.py"])
-```
-
-## Solution
-
-When you run the above code block, you will get the version of Python that is on the system path—not necessarily the Python executable installed in the virtual environment that the Streamlit code is running under.
-
-The solution is to detect the Python executable directy with [`sys.executable`](https://docs.python.org/3/library/sys.html#sys.executable):
-
-```python
-# streamlit_app.py
-import streamlit as st
-import subprocess
-import sys
-
-subprocess.run([f"{sys.executable}", "script.py"])
-```
-
-This ensures that `script.py` is running under the same Python executable as your Streamlit code—where your [Python dependencies](/streamlit-community-cloud/deploy-your-app/app-dependencies#add-python-dependencies) are installed.
-
-### Relevant links
-
-- https://stackoverflow.com/questions/69947867/run-portion-of-python-code-in-parallel-from-a-streamlit-app/69948545#69948545
-- https://discuss.streamlit.io/t/modulenotfounderror-no-module-named-cv2-streamlit/18319/3?u=snehankekre
-- https://docs.python.org/3/library/sys.html#sys.executable
diff --git a/data/kb/deployments/login-attempt-to-streamlit-community-cloud-fails-with-error-403.md b/data/kb/deployments/login-attempt-to-streamlit-community-cloud-fails-with-error-403.md
deleted file mode 100644
index 908281668..000000000
--- a/data/kb/deployments/login-attempt-to-streamlit-community-cloud-fails-with-error-403.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: Login attempt to Streamlit Community Cloud fails with error 403
-slug: /knowledge-base/deploy/login-attempt-to-streamlit-community-cloud-fails-with-error-403
----
-
-# Login attempt to Streamlit Community Cloud fails with error 403
-
-## Problem
-
-Streamlit Community Cloud has monitoring jobs to detect malicious users using the platform for crypto mining. These jobs sometimes result in false positives and a normal user starts getting error 403 against a login attempt.
-
-## Solution
-
-Please contact [Support](mailto:support@streamlit.io) by providing your **GitHub username** for help referring to this article.
diff --git a/data/kb/deployments/organize-apps-workspaces.md b/data/kb/deployments/organize-apps-workspaces.md
deleted file mode 100644
index 3a22952f8..000000000
--- a/data/kb/deployments/organize-apps-workspaces.md
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: Organizing your apps with workspaces on Streamlit Community Cloud
-slug: /knowledge-base/deploy/organizing-apps-workspaces-streamlit-cloud
----
-
-# Organizing your apps with workspaces on Streamlit Community Cloud
-
-Streamlit Community Cloud is organized into workspaces, which automatically group your apps according to the corresponding GitHub repository's owner. If you are part of multiple repositories, then you will have multiple workspaces.
-
-
-
-## Personal workspace
-
-If an app's GitHub repository is owned by you, the app will appear in your personal workspace, named "".
-
-
-
-## Organization workspace
-
-If an app's GitHub repository is owned by **an organization** (such as your company), the app will appear in a separate workspace, named "".
-
-
-
-## Workspaces with view access
-
-You will also have access to any workspaces containing app(s) for which you only have **view access**. These apps will have a "view-only" tooltip when you click on their respective overflow menu icons (⋮).
-
-
-
-## Switching between workspaces
-
-To switch between workspaces, click on the workspace listed in the top right corner, then select the desired workspace name.
-
-
-
-
-
-If you have further questions about workspaces on Streamlit Community Cloud, please emails us at [success@streamlit.io](mailto:success@streamlit.io).
-
-
diff --git a/data/kb/deployments/remote-start.md b/data/kb/deployments/remote-start.md
deleted file mode 100644
index 72ad230f1..000000000
--- a/data/kb/deployments/remote-start.md
+++ /dev/null
@@ -1,109 +0,0 @@
----
-title: App is not loading when running remotely
-slug: /knowledge-base/deploy/remote-start
----
-
-# App is not loading when running remotely
-
-Below are a few common errors that occur when users spin up their own solution
-to host a Streamlit app remotely.
-
-To learn about a deceptively simple way to host Streamlit apps that avoids all
-the issues below, check out [Streamlit Community Cloud](https://streamlit.io/cloud).
-
-### Symptom #1: The app never loads
-
-When you enter the app's URL in a browser and all you see is a **blank page, a
-"Page not found" error, a "Connection refused" error**, or anything like that,
-first check that Streamlit is actually running on the remote server. On a Linux
-server you can SSH into it and then run:
-
-```bash
-ps -Al | grep streamlit
-```
-
-If you see Streamlit running, the most likely culprit is the Streamlit port not
-being exposed. The fix depends on your exact setup. Below are three example
-fixes:
-
-- **Try port 80:** Some hosts expose port 80 by default. To
- set Streamlit to use that port, start Streamlit with the `--server.port`
- option:
-
- ```bash
- streamlit run my_app.py --server.port=80
- ```
-
-- **AWS EC2 server**: First, click on your instance in the [AWS Console](https://us-west-2.console.aws.amazon.com/ec2/v2/home).
- Then scroll down and click on _Security Groups_ → _Inbound_ → _Edit_. Next, add
- a _Custom TCP_ rule that allows the _Port Range_ `8501` with _Source_
- `0.0.0.0/0`.
-
-- **Other types of server**: Check the firewall settings.
-
-If that still doesn't solve the problem, try running a simple HTTP server
-instead of Streamlit, and seeing if _that_ works correctly. If it does, then
-you know the problem lies somewhere in your Streamlit app or configuration (in
-which case you should ask for help in our
-[forums](https://discuss.streamlit.io)!) If not, then it's definitely unrelated
-to Streamlit.
-
-How to start a simple HTTP server:
-
-```bash
-python -m http.server [port]
-```
-
-### Symptom #2: The app says "Please wait..." forever
-
-If when you try to load your app in a browser you see a blue box in the center
-of the page with the text "Please wait...", the underlying cause is likely one
-of the following:
-
-- Misconfigured [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
- protection.
-- Server is stripping headers from the Websocket connection, thereby breaking
- compression.
-
-To diagnose the issue, try temporarily disabling CORS protection by running
-Streamlit with the `--server.enableCORS` flag set to `false`:
-
-```bash
-streamlit run my_app.py --server.enableCORS=false
-```
-
-If this fixes your issue, **you should re-enable CORS protection** and then set
-`browser.serverPort` and `browser.serverAddress` to the URL and port of your
-Streamlit app.
-
-If the issue persists, try disabling websocket compression by running Streamlit with the
-`--server.enableWebsocketCompression` flag set to `false`
-
-```bash
-streamlit run my_app.py --server.enableWebsocketCompression=false
-```
-
-If this fixes your issue, your server setup is likely stripping the
-`Sec-WebSocket-Extensions` HTTP header that is used to negotiate Websocket compression.
-
-Compression is not required for Streamlit to work, but it's strongly recommended as it
-improves performance. If you'd like to turn it back on, you'll need to find which part
-of your infrastructure is stripping the `Sec-WebSocket-Extensions` HTTP header and
-change that behavior.
-
-### Symptom #3: Unable to upload files when running in multiple replicas
-
-If the file uploader widget returns an error with status code 403, this is probably
-due to a misconfiguration in your app's
-[XSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery) protection logic.
-
-To diagnose the issue, try temporarily disabling XSRF protection by running Streamlit
-with the `--server.enableXsrfProtection` flag set to `false`:
-
-```bash
-streamlit run my_app.py --server.enableXsrfProtection=false
-```
-
-If this fixes your issue, **you should re-enable XSRF protection** and then
-configure your app to use the same secret across every replica by setting the
-`server.cookieSecret` config option to the same hard-to-guess string everywhere.
diff --git a/data/kb/deployments/resource-limits.md b/data/kb/deployments/resource-limits.md
deleted file mode 100644
index 7e44a925e..000000000
--- a/data/kb/deployments/resource-limits.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: Argh. This app has gone over its resource limits
-slug: /knowledge-base/deploy/resource-limits
----
-
-# Argh. This app has gone over its resource limits
-
-Sorry! It means you've hit the [resource limits](/streamlit-community-cloud/manage-your-app#app-resources-and-limits) of your [Streamlit Community Cloud](https://streamlit.io/cloud) account.
-
-
-
-There are a few things you can change in your app to make it less resource-hungry:
-
-- Reboot your app (temporary fix)
-- Use `st.cache_data` or `st.cache_resource` to load models or data only once
-- Restrict the cache size with `ttl` or `max_entries`
-- Move big datasets to a database
-- Profile your app's memory usage
-
-Check out our [blog post](https://blog.streamlit.io/common-app-problems-resource-limits/) on [“Common app problems: Resource limits"](https://blog.streamlit.io/common-app-problems-resource-limits/) for more in-depth tips prevent your app from hitting the [resource limits](/streamlit-community-cloud/manage-your-app#app-resources-and-limits) of the Streamlit Community Cloud.
-
-Related forum posts:
-
--
--
-
-We offer free resource increases only to support nonprofits or educational organizations on a case-by-case basis. If you are a nonprofit or educational organization, please complete [this form](https://docs.google.com/forms/d/e/1FAIpQLSfzPNqrvH0HeaJnl0dtBgVV-ILqavzSmAEk84vDnMFIbvkGVA/viewform) and we will review your submission as soon as possible.
-
-Once the increase is completed, you will receive an email from the Streamlit marketing team with a confirmation that the increase has been applied.
diff --git a/data/kb/deployments/sign-in-email.md b/data/kb/deployments/sign-in-email.md
deleted file mode 100644
index 5c8381cd7..000000000
--- a/data/kb/deployments/sign-in-email.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: I don't have GitHub or GSuite. How do I sign in to Streamlit Community Cloud?
-slug: /knowledge-base/deploy/sign-in-without-sso
----
-
-# I don't have GitHub or GSuite. How do I sign in to Streamlit Community Cloud?
-
-If you don't have GitHub or GSuite accounts, you can sign in with your email address! Visit [share.streamlit.io](https://share.streamlit.io), enter the email address you used to sign up for Streamlit Community Cloud, and click the "Continue with email" button.
-
-
-
-Once you do so, you will see a confirmation message (like the one below) asking you to check your email.
-
-
-
-Check your inbox for an email from Streamlit, with the subject "Sign in to Streamlit Community Cloud". Click the link in the email to sign in to Streamlit. Note that this link will expire in 15 minutes and can only be used once.
-
-
-
-Once you click the link in your email, you will be taken to your Streamlit Community Cloud workspace!🎈
-
-
diff --git a/data/kb/deployments/unable-to-edit-or-delete-apps-in-streamlit-community-cloud-after-modifying-github-username.md b/data/kb/deployments/unable-to-edit-or-delete-apps-in-streamlit-community-cloud-after-modifying-github-username.md
deleted file mode 100644
index 91abc4923..000000000
--- a/data/kb/deployments/unable-to-edit-or-delete-apps-in-streamlit-community-cloud-after-modifying-github-username.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: Unable to edit or delete apps in Streamlit Community Cloud after modifying GitHub username
-slug: /knowledge-base/deploy/unable-to-edit-or-delete-apps-in-streamlit-community-cloud-after-modifying-github-username
----
-
-# Unable to edit or delete apps in Streamlit Community Cloud after modifying GitHub username
-
-## Problem
-
-After updating the GitHub username, apps cannot be edited or deleted from Streamlit Community Cloud.
-
-## Solution
-
-- Support can delete your old applications that were deployed before updating the GitHub username.
-- Once deleted, you can redeploy the applications using the new GitHub username.
-- Please contact [Support](mailto:support@streamlit.io) with **a list of the URLs for the apps** you need to be deleted.
diff --git a/data/kb/deployments/upgrade-streamlit-version.md b/data/kb/deployments/upgrade-streamlit-version.md
deleted file mode 100644
index 814ea8b73..000000000
--- a/data/kb/deployments/upgrade-streamlit-version.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: Upgrade the Streamlit version of your app on Streamlit Community Cloud
-slug: /knowledge-base/deploy/upgrade-streamlit-version-on-streamlit-cloud
----
-
-# Upgrade the Streamlit version of your app on Streamlit Community Cloud
-
-Want to use a cool new Streamlit feature but your app on Streamlit Community Cloud is running an old version of the Streamlit library? If that's you, don't worry! All you need to do is upgrade your app's Streamlit version. Here are five ways to do this, based on how your [app manages dependencies](/streamlit-community-cloud/deploy-your-app/app-dependencies):
-
-## No dependency file
-
-When there is no dependency file in the repo, the app will always use the same Streamlit version that existed when the app was _first_ deployed on Streamlit Community Cloud; even if you reboot the app! In other words, Streamlit Community Cloud automatically pins the version for you so that the app does not break suddenly when rebooted in the future.
-
-You may want to avoid getting into this situation if your app depends on a specific version of Streamlit. That is why we encourage you to use a dependency file and pin your desired version of Streamlit. We cover this in more detail in the sections below.
-
-## `requirements.txt`
-
-1. If the Streamlit version is not pinned (i.e., the requirements file contains a line with `streamlit` and nothing else):
- - Reboot the app as described above.
-2. If the Streamlit version is pinned (e.g., `streamlit==1.4.0`):
- - Adapt the pinned version in the requirements file and push it to GitHub.
- - The app on Streamlit Community Cloud will reboot automatically as soon as it detects these changes.
-
-## pipenv/poetry/conda
-
-If you use any of these dependency managers, you probably know what you need to do. 😉
-
-1. On your local computer, run the command to update the Streamlit package:
- - `pipenv update streamlit` or
- - `poetry update streamlit` or
- - With an activated conda environment, run:
- - `pip install -U streamlit` **and**
- - `conda env export`
-2. Then push any changes to Pipfile.lock or poetry.lock or environment.yml to GitHub.
-3. The app on Streamlit Community Cloud will reboot automatically as soon as it detects these changes.
diff --git a/data/kb/deployments/view-only-access-to-app-after-changing-github-username-or-repository-name.md b/data/kb/deployments/view-only-access-to-app-after-changing-github-username-or-repository-name.md
deleted file mode 100644
index 686b9c98c..000000000
--- a/data/kb/deployments/view-only-access-to-app-after-changing-github-username-or-repository-name.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: View-only access to app after changing GitHub username or repository name
-slug: /knowledge-base/deploy/view-only-access-to-app-after-changing-github-username-or-repository-name
----
-
-# View-only access to app after changing GitHub username or repository name
-
-This KB helps to resolve the issue of the apps becoming view-only.
-
-## Problem
-
-When opening the dropdown menu of the apps on Streamlit Community CLoud, the options Reboot, Delete and Settings is grayed out, and there is a message "You have view-only access to this application".
-
-
-
-Changing your GitHub username or the repository name after deploying an app causes your app to become view-only.
-
-## Solution
-
-Please reach out to the [Snowflake support team](mailto:support@streamlit.io) to delete the affected app(s) for you so you can redeploy them with your new username.
diff --git a/data/kb/index.md b/data/kb/index.md
deleted file mode 100644
index 5e46d6077..000000000
--- a/data/kb/index.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: Knowledge Base
-slug: /knowledge-base
----
-
-# Knowledge base
-
-The knowledge base is a self-serve library of tips, step-by-step tutorials, and articles that answer your questions about creating and deploying Streamlit apps.
-
-
-
- Our tutorials include step-by-step examples of building different types of apps in Streamlit.
-
-
- Here are some frequently asked questions about using Streamlit.
-
-
- Here are some questions we've received about Streamlit Components.
-
-
- If you run into problems installing depedencies for your Streamlit apps, we've got you covered.
-
-
- Have questions about deploying Streamlit apps to the cloud? This section covers deployment-related issues.
-
-
diff --git a/data/kb/tutorials/chat.md b/data/kb/tutorials/chat.md
deleted file mode 100644
index 6cacdd010..000000000
--- a/data/kb/tutorials/chat.md
+++ /dev/null
@@ -1,439 +0,0 @@
----
-title: Build conversational apps
-slug: /knowledge-base/tutorials/build-conversational-apps
----
-
-# Build conversational apps
-
-## Introduction
-
-The advent of large language models like GPT has revolutionized the ease of developing chat-based applications. Streamlit offers several [Chat elements](/library/api-reference/chat), enabling you to build Graphical User Interfaces (GUIs) for conversational agents or chatbots. Leveraging [session state](/library/advanced-features/session-state) along with these elements allows you to construct anything from a basic chatbot to a more advanced, ChatGPT-like experience using purely Python code.
-
-
-
-In this tutorial, we'll start by walking through Streamlit's chat elements, `st.chat_message` and `st.chat_input`. Then we'll proceed to construct three distinct applications, each showcasing an increasing level of complexity and functionality:
-
-1. First, we'll [Build a bot that mirrors your input](#build-a-bot-that-mirrors-your-input) to get a feel for the chat elements and how they work. We'll also introduce [session state](/library/advanced-features/session-state) and how it can be used to store the chat history. This section will serve as a foundation for the rest of the tutorial.
-2. Next, you'll learn how to [Build a simple chatbot GUI with streaming](#build-a-simple-chatbot-gui-with-streaming).
-3. Finally, we'll [Build a ChatGPT-like app](#build-a-chatgpt-like-app) that leverages session state to remember conversational context, all within less than 50 lines of code.
-
-Here's a sneak peek of the LLM-powered chatbot GUI with streaming we'll build in this tutorial:
-
-
-
-Play around with the above demo to get a feel for what we'll build in this tutorial. A few things to note:
-
-- There's a chat input at the bottom of the screen that's always visible. It contains some placeholder text. You can type in a message and press Enter or click the run button to send it.
-- When you enter a message, it appears as a chat message in the container above. The container is scrollable, so you can scroll up to see previous messages. A default avatar is displayed to your messages' left.
-- The assistant's responses are streamed to the frontend and are displayed with a different default avatar.
-
-Before we start building, let's take a closer look at the chat elements we'll use.
-
-## Chat elements
-
-Streamlit offers several commands to help you build conversational apps. These chat elements are designed to be used in conjunction with each other, but you can also use them separately.
-
-[`st.chat_message`](/library/api-reference/chat/st.chat_message) lets you insert a chat message container into the app so you can display messages from the user or the app. Chat containers can contain other Streamlit elements, including charts, tables, text, and more. [`st.chat_input`](/library/api-reference/chat/st.chat_input) lets you display a chat input widget so the user can type in a message.
-
-For an overview of the API, check out this video tutorial by Chanin Nantasenamat ([@dataprofessor](https://www.youtube.com/dataprofessor)), a Senior Developer Advocate at Streamlit.
-
-
-
-### st.chat_message
-
-`st.chat_message` lets you insert a multi-element chat message container into your app. The returned container can contain any Streamlit element, including charts, tables, text, and more. To add elements to the returned container, you can use `with` notation.
-
-`st.chat_message`'s first parameter is the `name` of the message author, which can be either `"user"` or `"assistant"` to enable preset styling and avatars, like in the demo above. You can also pass in a custom string to use as the author name. Currently, the name is not shown in the UI but is only set as an accessibility label. For accessibility reasons, you should not use an empty string.
-
-Here's an minimal example of how to use `st.chat_message` to display a welcome message:
-
-```python
-import streamlit as st
-
-with st.chat_message("user"):
- st.write("Hello 👋")
-```
-
-
-
-
-Notice the message is displayed with a default avatar and styling since we passed in `"user"` as the author name. You can also pass in `"assistant"` as the author name to use a different default avatar and styling, or pass in a custom name and avatar. See the [API reference](/library/api-reference/chat/st.chat_message) for more details.
-
-```python
-import streamlit as st
-import numpy as np
-
-with st.chat_message("assistant"):
- st.write("Hello human")
- st.bar_chart(np.random.randn(30, 3))
-```
-
-
-
-While we've used the preferred `with` notation in the above examples, you can also just call methods directly in the returned objects. The below example is equivalent to the one above:
-
-```python
-import streamlit as st
-import numpy as np
-
-message = st.chat_message("assistant")
-message.write("Hello human")
-message.bar_chart(np.random.randn(30, 3))
-```
-
-So far, we've displayed predefined messages. But what if we want to display messages based on user input?
-
-### st.chat_input
-
-`st.chat_input` lets you display a chat input widget so the user can type in a message. The returned value is the user's input, which is `None` if the user hasn't sent a message yet. You can also pass in a default prompt to display in the input widget. Here's an example of how to use `st.chat_input` to display a chat input widget and show the user's input:
-
-```python
-import streamlit as st
-
-prompt = st.chat_input("Say something")
-if prompt:
- st.write(f"User has sent the following prompt: {prompt}")
-```
-
-
-
-Pretty straightforward, right? Now let's combine `st.chat_message` and `st.chat_input` to build a bot the mirrors or echoes your input.
-
-## Build a bot that mirrors your input
-
-In this section, we'll build a bot that mirrors or echoes your input. More specifically, the bot will respond to your input with the same message. We'll use `st.chat_message` to display the user's input and `st.chat_input` to accept user input. We'll also use [session state](/library/advanced-features/session-state) to store the chat history so we can display it in the chat message container.
-
-First, let's think about the different components we'll need to build our bot:
-
-- Two chat message containers to display messages from the user and the bot, respectively.
-- A chat input widget so the user can type in a message.
-- A way to store the chat history so we can display it in the chat message containers. We can use a list to store the messages, and append to it every time the user or bot sends a message. Each entry in the list will be a dictionary with the following keys: `role` (the author of the message), and `content` (the message content).
-
-```python
-import streamlit as st
-
-st.title("Echo Bot")
-
-# Initialize chat history
-if "messages" not in st.session_state:
- st.session_state.messages = []
-
-# Display chat messages from history on app rerun
-for message in st.session_state.messages:
- with st.chat_message(message["role"]):
- st.markdown(message["content"])
-```
-
-In the above snippet, we've added a title to our app and a for loop to iterate through the chat history and display each message in the chat message container (with the author role and message content). We've also added a check to see if the `messages` key is in `st.session_state`. If it's not, we initialize it to an empty list. This is because we'll be adding messages to the list later on, and we don't want to overwrite the list every time the app reruns.
-
-Now let's accept user input with `st.chat_input`, display the user's message in the chat message container, and add it to the chat history.
-
-```python
-# React to user input
-if prompt := st.chat_input("What is up?"):
- # Display user message in chat message container
- with st.chat_message("user"):
- st.markdown(prompt)
- # Add user message to chat history
- st.session_state.messages.append({"role": "user", "content": prompt})
-```
-
-We used the `:=` operator to assign the user's input to the `prompt` variable and checked if it's not `None` in the same line. If the user has sent a message, we display the message in the chat message container and append it to the chat history.
-
-All that's left to do is add the chatbot's responses within the `if` block. We'll use the same logic as before to display the bot's response (which is just the user's prompt) in the chat message container and add it to the history.
-
-```python
-response = f"Echo: {prompt}"
-# Display assistant response in chat message container
-with st.chat_message("assistant"):
- st.markdown(response)
-# Add assistant response to chat history
-st.session_state.messages.append({"role": "assistant", "content": response})
-```
-
-Putting it all together, here's the full code for our simple chatbot GUI and the result:
-
-
-
-```python
-import streamlit as st
-
-st.title("Echo Bot")
-
-# Initialize chat history
-if "messages" not in st.session_state:
- st.session_state.messages = []
-
-# Display chat messages from history on app rerun
-for message in st.session_state.messages:
- with st.chat_message(message["role"]):
- st.markdown(message["content"])
-
-# React to user input
-if prompt := st.chat_input("What is up?"):
- # Display user message in chat message container
- st.chat_message("user").markdown(prompt)
- # Add user message to chat history
- st.session_state.messages.append({"role": "user", "content": prompt})
-
- response = f"Echo: {prompt}"
- # Display assistant response in chat message container
- with st.chat_message("assistant"):
- st.markdown(response)
- # Add assistant response to chat history
- st.session_state.messages.append({"role": "assistant", "content": response})
-```
-
-
-
-
-
-While the above example is very simple, it's a good starting point for building more complex conversational apps. Notice how the bot responds instantly to your input. In the next section, we'll add a delay to simulate the bot "thinking" before responding.
-
-## Build a simple chatbot GUI with streaming
-
-In this section, we'll build a simple chatbot GUI that responds to user input with a random message from a list of pre-determind responses. In the [next section](#build-a-chatgpt-like-app), we'll convert this simple toy example into a ChatGPT-like experience using OpenAI.
-
-Just like previously, we still require the same components to build our chatbot. Two chat message containers to display messages from the user and the bot, respectively. A chat input widget so the user can type in a message. And a way to store the chat history so we can display it in the chat message containers.
-
-Let's just copy the code from the previous section and add a few tweaks to it.
-
-```python
-import streamlit as st
-import random
-import time
-
-st.title("Simple chat")
-
-# Initialize chat history
-if "messages" not in st.session_state:
- st.session_state.messages = []
-
-# Display chat messages from history on app rerun
-for message in st.session_state.messages:
- with st.chat_message(message["role"]):
- st.markdown(message["content"])
-
-# Accept user input
-if prompt := st.chat_input("What is up?"):
- # Display user message in chat message container
- with st.chat_message("user"):
- st.markdown(prompt)
- # Add user message to chat history
- st.session_state.messages.append({"role": "user", "content": prompt})
-```
-
-The only difference so far is we've changed the title of our app and added imports for `random` and `time`. We'll use `random` to randomly select a response from a list of responses and `time` to add a delay to simulate the chatbot "thinking" before responding.
-
-All that's left to do is add the chatbot's responses within the `if` block. We'll use a list of responses and randomly select one to display. We'll also add a delay to simulate the chatbot "thinking" before responding (or stream its response).
-
-```python
-# Display assistant response in chat message container
-with st.chat_message("assistant"):
- message_placeholder = st.empty()
- full_response = ""
- assistant_response = random.choice(
- [
- "Hello there! How can I assist you today?",
- "Hi, human! Is there anything I can help you with?",
- "Do you need help?",
- ]
- )
- # Simulate stream of response with milliseconds delay
- for chunk in assistant_response.split():
- full_response += chunk + " "
- time.sleep(0.05)
- # Add a blinking cursor to simulate typing
- message_placeholder.markdown(full_response + "▌")
- message_placeholder.markdown(full_response)
-# Add assistant response to chat history
-st.session_state.messages.append({"role": "assistant", "content": full_response})
-```
-
-Above, we've added a placeholder to display the chatbot's response. We've also added a for loop to iterate through the response and display it one word at a time. We've added a delay of 0.05 seconds between each word to simulate the chatbot "thinking" before responding. Finally, we append the chatbot's response to the chat history. As you've probably guessed, this is a naive implementation of streaming. We'll see how to implement streaming with OpenAI in the [next section](#build-a-chatgpt-like-app).
-
-Putting it all together, here's the full code for our simple chatbot GUI and the result:
-
-
-
-```python
-import streamlit as st
-import random
-import time
-
-st.title("Simple chat")
-
-# Initialize chat history
-if "messages" not in st.session_state:
- st.session_state.messages = []
-
-# Display chat messages from history on app rerun
-for message in st.session_state.messages:
- with st.chat_message(message["role"]):
- st.markdown(message["content"])
-
-# Accept user input
-if prompt := st.chat_input("What is up?"):
- # Add user message to chat history
- st.session_state.messages.append({"role": "user", "content": prompt})
- # Display user message in chat message container
- with st.chat_message("user"):
- st.markdown(prompt)
-
- # Display assistant response in chat message container
- with st.chat_message("assistant"):
- message_placeholder = st.empty()
- full_response = ""
- assistant_response = random.choice(
- [
- "Hello there! How can I assist you today?",
- "Hi, human! Is there anything I can help you with?",
- "Do you need help?",
- ]
- )
- # Simulate stream of response with milliseconds delay
- for chunk in assistant_response.split():
- full_response += chunk + " "
- time.sleep(0.05)
- # Add a blinking cursor to simulate typing
- message_placeholder.markdown(full_response + "▌")
- message_placeholder.markdown(full_response)
- # Add assistant response to chat history
- st.session_state.messages.append({"role": "assistant", "content": full_response})
-```
-
-
-
-
-
-Play around with the above demo to get a feel for what we've built. It's a very simple chatbot GUI, but it has all the components of a more sophisticated chatbot. In the next section, we'll see how to build a ChatGPT-like app using OpenAI.
-
-## Build a ChatGPT-like app
-
-Now that you've understood the basics of Streamlit's chat elements, let's make a few tweaks to it to build our own ChatGPT-like app. You'll need to install the [OpenAI Python library](https://pypi.org/project/openai/) and get an [API key](https://platform.openai.com/account/api-keys) to follow along.
-
-### Install dependencies
-
-First let's install the dependencies we'll need for this section:
-
-```bash
-pip install openai streamlit
-```
-
-### Add OpenAI API key to Streamlit secrets
-
-Next, let's add our OpenAI API key to [Streamlit secrets](/library/advanced-features/secrets-management). We do this by creating `.streamlit/secrets.toml` file in our project directory and adding the following lines to it:
-
-```toml
-# .streamlit/secrets.toml
-OPENAI_API_KEY = "YOUR_API_KEY"
-```
-
-### Write the app
-
-Now let's write the app. We'll use the same code as before, but we'll replace the list of responses with a call to the OpenAI API. We'll also add a few more tweaks to make the app more ChatGPT-like.
-
-```python
-import streamlit as st
-import openai
-
-st.title("ChatGPT-like clone")
-
-# Set OpenAI API key from Streamlit secrets
-openai.api_key = st.secrets["OPENAI_API_KEY"]
-
-# Set a default model
-if "openai_model" not in st.session_state:
- st.session_state["openai_model"] = "gpt-3.5-turbo"
-
-# Initialize chat history
-if "messages" not in st.session_state:
- st.session_state.messages = []
-
-# Display chat messages from history on app rerun
-for message in st.session_state.messages:
- with st.chat_message(message["role"]):
- st.markdown(message["content"])
-
-# Accept user input
-if prompt := st.chat_input("What is up?"):
- # Add user message to chat history
- st.session_state.messages.append({"role": "user", "content": prompt})
- # Display user message in chat message container
- with st.chat_message("user"):
- st.markdown(prompt)
- # Display assistant response in chat message container
- with st.chat_message("assistant"):
- message_placeholder = st.empty()
- full_response = ""
-```
-
-All that's changed is that we've added a default model to `st.session_state` and set our OpenAI API key from Streamlit secrets. Here's where it gets interesting. We can replace our logic from earlier to emulate streaming predetermind responses with the model's responses from OpenAI:
-
-```python
- for response in openai.ChatCompletion.create(
- model=st.session_state["openai_model"],
- messages=[{"role": m["role"], "content": m["content"]} for m in st.session_state.messages],
- stream=True,
- ):
- full_response += response.choices[0].delta.get("content", "")
- message_placeholder.markdown(full_response + "▌")
- message_placeholder.markdown(full_response)
-st.session_state.messages.append({"role": "assistant", "content": full_response})
-```
-
-Above, we've replaced the list of responses with a call to [`openai.ChatCompletion.create`](https://platform.openai.com/docs/guides/gpt/chat-completions-api). We've set `stream=True` to stream the responses to the frontend. In the API call, we pass the model name we hardcoded in session state and pass the chat history as a list of messages. We also pass the `role` and `content` of each message in the chat history. Finally, OpenAI returns a stream of responses (split into chunks of tokens), which we iterate through and display each chunk.
-
-Putting it all together, here's the full code for our ChatGPT-like app and the result:
-
-
-
-```python
-import openai
-import streamlit as st
-
-st.title("ChatGPT-like clone")
-
-openai.api_key = st.secrets["OPENAI_API_KEY"]
-
-if "openai_model" not in st.session_state:
- st.session_state["openai_model"] = "gpt-3.5-turbo"
-
-if "messages" not in st.session_state:
- st.session_state.messages = []
-
-for message in st.session_state.messages:
- with st.chat_message(message["role"]):
- st.markdown(message["content"])
-
-if prompt := st.chat_input("What is up?"):
- st.session_state.messages.append({"role": "user", "content": prompt})
- with st.chat_message("user"):
- st.markdown(prompt)
-
- with st.chat_message("assistant"):
- message_placeholder = st.empty()
- full_response = ""
- for response in openai.ChatCompletion.create(
- model=st.session_state["openai_model"],
- messages=[
- {"role": m["role"], "content": m["content"]}
- for m in st.session_state.messages
- ],
- stream=True,
- ):
- full_response += response.choices[0].delta.get("content", "")
- message_placeholder.markdown(full_response + "▌")
- message_placeholder.markdown(full_response)
- st.session_state.messages.append({"role": "assistant", "content": full_response})
-```
-
-
-
-
-
-
-
-Congratulations! You've built your own ChatGPT-like app in less than 50 lines of code.
-
-We're very excited to see what you'll build with Streamlit's chat elements. Experiment with different models and tweak the code to build your own conversational apps. If you build something cool, let us know on the [Forum](https://discuss.streamlit.io/c/streamlit-examples/9) or check out some other [Generative AI apps](https://streamlit.io/generative-ai) for inspiration. 🎈
diff --git a/data/kb/tutorials/databases/aws-s3.md b/data/kb/tutorials/databases/aws-s3.md
deleted file mode 100644
index 5db448aa2..000000000
--- a/data/kb/tutorials/databases/aws-s3.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: Connect Streamlit to AWS S3
-slug: /knowledge-base/tutorials/databases/aws-s3
----
-
-# Connect Streamlit to AWS S3
-
-## Introduction
-
-This guide explains how to securely access files on AWS S3 from Streamlit Community Cloud. It uses [Streamlit FilesConnection](https://github.com/streamlit/files-connection), the [s3fs](https://github.com/dask/s3fs) library and optionally Streamlit's [Secrets management](/library/advanced-features/secrets-management).
-
-## Create an S3 bucket and add a file
-
-
-
-If you already have a bucket that you want to use, feel free
-to [skip to the next step](#create-access-keys).
-
-
-
-First, [sign up for AWS](https://aws.amazon.com/) or log in. Go to the [S3 console](https://s3.console.aws.amazon.com/s3/home) and create a new bucket:
-
-
-
-
-
-
-Navigate to the upload section of your new bucket:
-
-
-
-
-
-
-And note down the "AWS Region" for later. In this example, it's `us-east-1`, but it may differ for you.
-
-Next, upload the following CSV file, which contains some example data:
-
-myfile.csv
-
-## Create access keys
-
-Go to the [AWS console](https://console.aws.amazon.com/), create access keys as shown below and copy the "Access Key ID" and "Secret Access Key":
-
-
-
-
-
-
-
-
-Access keys created as a root user have wide-ranging permissions. In order to make your AWS account
-more secure, you should consider creating an IAM account with restricted permissions and using its
-access keys. More information [here](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html).
-
-
-
-## Set up your AWS credentials locally
-
-Streamlit FilesConnection and s3fs will read and use your existing [AWS credentials and configuration](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html) if available - such as from an `~/.aws/credentials` file or environment variables.
-
-If you don't already have this set up, or plan to host the app on Streamlit Community Cloud, you should specify the credentials from a file `.streamlit/secrets.toml` in your app's root directory or your home directory. Create this file if it doesn't exist yet and add to it the access key ID, access key secret, and the AWS default region you noted down earlier, as shown below:
-
-```toml
-# .streamlit/secrets.toml
-AWS_ACCESS_KEY_ID = "xxx"
-AWS_SECRET_ACCESS_KEY = "xxx"
-AWS_DEFAULT_REGION = "xxx"
-```
-
-
-
-Be sure to replace `xxx` above with the values you noted down earlier, and add this file to `.gitignore` so you don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-To host your app on Streamlit Community Cloud, you will need to pass your credentials to your deployed app via secrets. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` above into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add FilesConnection and s3fs to your requirements file
-
-Add the [FilesConnection](https://github.com/streamlit/files-connection) and [s3fs](https://github.com/dask/s3fs) packages to your `requirements.txt` file, preferably pinning the versions (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-s3fs==x.x.x
-# Direct pypi install coming soon
-git+https://github.com/streamlit/files-connection
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt the name of your bucket and file. Note that Streamlit automatically turns the access keys from your secrets file into environment variables, where `s3fs` searches for them by default.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-from st_files_connection import FilesConnection
-
-# Create connection object and retrieve file contents.
-# Specify input format is a csv and to cache the result for 600 seconds.
-conn = st.experimental_connection('s3', type=FilesConnection)
-df = conn.read("testbucket-jrieke/myfile.csv", input_format="csv", ttl=600)
-
-# Print results.
-for row in df.itertuples():
- st.write(f"{row.Owner} has a :{row.Pet}:")
-```
-
-See `st.experimental_connection` above? This handles secrets retrieval, setup, result caching and retries. By default, `read()` results are cached without expiring. In this case, we set `ttl=600` to ensure the file contents is cached for no longer than 10 minutes. You can also set `ttl=0` to disable caching. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example file given above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/bigquery.md b/data/kb/tutorials/databases/bigquery.md
deleted file mode 100644
index 03dbbf5b4..000000000
--- a/data/kb/tutorials/databases/bigquery.md
+++ /dev/null
@@ -1,144 +0,0 @@
----
-title: Connect Streamlit to Google BigQuery
-slug: /knowledge-base/tutorials/databases/bigquery
----
-
-# Connect Streamlit to Google BigQuery
-
-## Introduction
-
-This guide explains how to securely access a BigQuery database from Streamlit Community Cloud. It uses the
-[google-cloud-bigquery](https://googleapis.dev/python/bigquery/latest/index.html) library and
-Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-## Create a BigQuery database
-
-
-
-If you already have a database that you want to use, feel free
-to [skip to the next step](#enable-the-bigquery-api).
-
-
-
-For this example, we will use one of the [sample datasets](https://cloud.google.com/bigquery/public-data#sample_tables) from BigQuery (namely the `shakespeare` table). If you want to create a new dataset instead, follow [Google's quickstart guide](https://cloud.google.com/bigquery/docs/quickstarts/quickstart-web-ui).
-
-## Enable the BigQuery API
-
-Programmatic access to BigQuery is controlled through [Google Cloud Platform](https://cloud.google.com). Create an account or sign in and head over to the [APIs & Services dashboard](https://console.cloud.google.com/apis/dashboard) (select or create a project if asked). As shown below, search for the BigQuery API and enable it:
-
-
-
-
-
-
-
-## Create a service account & key file
-
-To use the BigQuery API from Streamlit Community Cloud, you need a Google Cloud Platform service account (a special account type for programmatic data access). Go to the [Service Accounts](https://console.cloud.google.com/iam-admin/serviceaccounts) page and create an account with the **Viewer** permission (this will let the account access data but not change it):
-
-
-
-
-
-
-
-
-
-If the button **CREATE SERVICE ACCOUNT** is gray, you don't have the correct permissions. Ask the
-admin of your Google Cloud project for help.
-
-
-
-After clicking **DONE**, you should be back on the service accounts overview. Create a JSON key file for the new account and download it:
-
-
-
-
-
-
-
-## Add the key file to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root
-directory. Create this file if it doesn't exist yet and add the content of the key file you just
-downloaded to it as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[gcp_service_account]
-type = "service_account"
-project_id = "xxx"
-private_key_id = "xxx"
-private_key = "xxx"
-client_email = "xxx"
-client_id = "xxx"
-auth_uri = "https://accounts.google.com/o/oauth2/auth"
-token_uri = "https://oauth2.googleapis.com/token"
-auth_provider_x509_cert_url = "https://www.googleapis.com/oauth2/v1/certs"
-client_x509_cert_url = "xxx"
-```
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add google-cloud-bigquery to your requirements file
-
-Add the [google-cloud-bigquery](https://googleapis.dev/python/bigquery/latest/index.html) package to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version want installed):
-
-```bash
-# requirements.txt
-google-cloud-bigquery==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt the query if you don't use the sample table.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-from google.oauth2 import service_account
-from google.cloud import bigquery
-
-# Create API client.
-credentials = service_account.Credentials.from_service_account_info(
- st.secrets["gcp_service_account"]
-)
-client = bigquery.Client(credentials=credentials)
-
-# Perform query.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def run_query(query):
- query_job = client.query(query)
- rows_raw = query_job.result()
- # Convert to list of dicts. Required for st.cache_data to hash the return value.
- rows = [dict(row) for row in rows_raw]
- return rows
-
-rows = run_query("SELECT word FROM `bigquery-public-data.samples.shakespeare` LIMIT 10")
-
-# Print results.
-st.write("Some wise words from Shakespeare:")
-for row in rows:
- st.write("✍️ " + row['word'])
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-Alternatively, you can use pandas to read from BigQuery right into a dataframe! Follow all the above steps, install the [pandas-gbq](https://pandas-gbq.readthedocs.io/en/latest/index.html) library (don't forget to add it to `requirements.txt`!), and call `pandas.read_gbq(query, credentials=credentials)`. More info [in the pandas docs](https://pandas.pydata.org/docs/reference/api/pandas.read_gbq.html).
-
-If everything worked out (and you used the sample table), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/detabase.md b/data/kb/tutorials/databases/detabase.md
deleted file mode 100644
index aa83ffa31..000000000
--- a/data/kb/tutorials/databases/detabase.md
+++ /dev/null
@@ -1,99 +0,0 @@
----
-title: Connect Streamlit to Deta Base
-slug: /knowledge-base/tutorials/databases/deta-base
----
-
-# Connect Streamlit to Deta Base
-
-## Introduction
-
-This guide explains how to securely access and write to a [Deta Base](https://deta.space/docs/en/reference/base/about) database from Streamlit Community Cloud. Deta Base is a fully-managed and fast NoSQL database with a focus on end-user simplicity. The data is stored in your own "personal cloud" on [Deta Space](https://deta.space/developers). This guide uses the [Deta Python SDK](https://github.com/deta/deta-python) for Deta Base and Streamlit's [Secrets management](https://www.notion.so/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-## Create an account and sign in to Deta Space
-
-First, you need to [create a Deta Space account](https://deta.space/signup?dev_mode=true) for using Deta Base. Make sure the "Developer Mode" option is enabled when signing up. Once you have an account, sign in to Deta Space. After signing in, open the Collections app by clicking on it.
-
-[Deta Collections](https://deta.space/manual/features/collections#what-are-collections) is a pre-installed app on Space that stores different types of data that can be connected to other apps or services.
-
-
-Now click on the **Get Started** button and then click on the **Create Collection** button after giving your Collection a name.
-
-
-After that, click on the **Collection Settings** option in the top corner, which will show the modal for creating a **Data Key**. Click on the **Create New Data Key** button, then give your key a name, and click the **Generate** button. Copy the key shown to your clipboard by clicking on the copy button.
-
-[Data Keys](https://deta.space/docs/en/basics/extending_apps#data-keys) allow you to read and manipulate data within your Collections.
-
-
-Be sure to store your **Data Key** securely. It is shown only once, and you will need it to connect to your Deta Base.
-
-## Add Data Key to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add the **Data Key** (from the previous step) of your Deta Base as shown below:
-
-```toml
-# .streamlit/secrets.toml
-data_key = "xxx"
-```
-
-Replace `xxx` above ☝️ with your **Data Key** from the previous step.
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add deta to your requirements file
-
-Add the [deta](https://github.com/deta/deta-python) Python SDK for Deta Base to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-deta==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. The example app below writes data from a Streamlit form to a Deta Base database `example-db`.
-
-```python
-import streamlit as st
-from deta import Deta
-
-# Data to be written to Deta Base
-with st.form("form"):
- name = st.text_input("Your name")
- age = st.number_input("Your age")
- submitted = st.form_submit_button("Store in database")
-
-
-# Connect to Deta Base with your Data Key
-deta = Deta(st.secrets["data_key"])
-
-# Create a new database "example-db"
-# If you need a new database, just use another name.
-db = deta.Base("example-db")
-
-# If the user clicked the submit button,
-# write the data from the form to the database.
-# You can store any data you want here. Just modify that dictionary below (the entries between the {}).
-if submitted:
- db.put({"name": name, "age": age})
-
-"---"
-"Here's everything stored in the database:"
-# This reads all items from the database and displays them to your app.
-# db_content is a list of dictionaries. You can do everything you want with it.
-db_content = db.fetch().items
-st.write(db_content)
-```
-
-If everything worked out (and you used the example we created above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/gcs.md b/data/kb/tutorials/databases/gcs.md
deleted file mode 100644
index 46dec9aa7..000000000
--- a/data/kb/tutorials/databases/gcs.md
+++ /dev/null
@@ -1,143 +0,0 @@
----
-title: Connect Streamlit to Google Cloud Storage
-slug: /knowledge-base/tutorials/databases/gcs
----
-
-# Connect Streamlit to Google Cloud Storage
-
-## Introduction
-
-This guide explains how to securely access files on Google Cloud Storage from Streamlit Community Cloud. It uses [Streamlit FilesConnection](https://github.com/streamlit/files-connection), the [gcsfs](https://github.com/fsspec/gcsfs) library and Streamlit's [Secrets management](/library/advanced-features/secrets-management).
-
-## Create a Google Cloud Storage bucket and add a file
-
-
-
-If you already have a bucket that you want to use, feel free
-to [skip to the next step](#enable-the-google-cloud-storage-api).
-
-
-
-First, [sign up for Google Cloud Platform](https://console.cloud.google.com/) or log in. Go to the [Google Cloud Storage console](https://console.cloud.google.com/storage/) and create a new bucket.
-
-
-
-
-
-
-Navigate to the upload section of your new bucket:
-
-
-
-
-
-
-And upload the following CSV file, which contains some example data:
-
-myfile.csv
-
-## Enable the Google Cloud Storage API
-
-The Google Cloud Storage API is [enabled by default](https://cloud.google.com/service-usage/docs/enabled-service#default) when you create a project through the Google Cloud Console or CLI. Feel free to [skip to the next step](#create-a-service-account-and-key-file).
-
-If you do need to enable the API for programmatic access in your project, head over to the [APIs & Services dashboard](https://console.cloud.google.com/apis/dashboard) (select or create a project if asked). Search for the Cloud Storage API and enable it. The screenshot below has a blue "Manage" button and indicates the "API is enabled" which means no further action needs to be taken. This is very likely what you have since the API is enabled by default. However, if that is not what you see and you have an "Enable" button, you'll need to enable the API:
-
-
-
-
-
-
-
-## Create a service account and key file
-
-To use the Google Cloud Storage API from Streamlit, you need a Google Cloud Platform service account (a special type for programmatic data access). Go to the Service Accounts page and create an account with Viewer permission.
-
-
-
-
-
-
-
-
-
-If the button **CREATE SERVICE ACCOUNT** is gray, you don't have the correct permissions. Ask the
-admin of your Google Cloud project for help.
-
-
-
-After clicking **DONE**, you should be back on the service accounts overview. Create a JSON key file for the new account and download it:
-
-
-
-
-
-
-
-## Add the key to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add the access key to it as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.gcs]
-type = "service_account"
-project_id = "xxx"
-private_key_id = "xxx"
-private_key = "xxx"
-client_email = "xxx"
-client_id = "xxx"
-auth_uri = "https://accounts.google.com/o/oauth2/auth"
-token_uri = "https://oauth2.googleapis.com/token"
-auth_provider_x509_cert_url = "https://www.googleapis.com/oauth2/v1/certs"
-client_x509_cert_url = "xxx"
-```
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add FilesConnection and gcsfs to your requirements file
-
-Add the [FilesConnection](https://github.com/streamlit/files-connection) and [gcsfs](https://github.com/fsspec/gcsfs) packages to your `requirements.txt` file, preferably pinning the versions (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-gcsfs==x.x.x
-# Direct pypi install coming soon
-git+https://github.com/streamlit/files-connection
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt the name of your bucket and file. Note that Streamlit automatically turns the access keys from your secrets file into environment variables.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-from st_files_connection import FilesConnection
-
-# Create connection object and retrieve file contents.
-# Specify input format is a csv and to cache the result for 600 seconds.
-conn = st.experimental_connection('gcs', type=FilesConnection)
-df = conn.read("streamlit-bucket/myfile.csv", input_format="csv", ttl=600)
-
-# Print results.
-for row in df.itertuples():
- st.write(f"{row.Owner} has a :{row.Pet}:")
-```
-
-See `st.experimental_connection` above? This handles secrets retrieval, setup, result caching and retries. By default, `read()` results are cached without expiring. In this case, we set `ttl=600` to ensure the file contents is cached for no longer than 10 minutes. You can also set `ttl=0` to disable caching. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example file given above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/index.md b/data/kb/tutorials/databases/index.md
deleted file mode 100644
index ed910cadb..000000000
--- a/data/kb/tutorials/databases/index.md
+++ /dev/null
@@ -1,140 +0,0 @@
----
-title: Connect to data sources
-slug: /knowledge-base/tutorials/databases
----
-
-# Connect Streamlit to data sources
-
-These step-by-step guides demonstrate how to connect Streamlit apps to various databases & APIs.
-They use Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management) and
-[caching](/library/advanced-features/caching) to provide secure and fast data access.
-
-
-
-
-
-
-
AWS S3
-
-
-
-
-
-
-
-
BigQuery
-
-
-
-
-
-
-
-
Deta Base
-
-
-
-
-
-
-
-
Firestore (blog)
-
-
-
-
-
-
-
-
Google Cloud Storage
-
-
-
-
-
-
-
-
Microsoft SQL Server
-
-
-
-
-
-
-
-
MongoDB
-
-
-
-
-
-
-
-
MySQL
-
-
-
-
-
-
-
-
PostgreSQL
-
-
-
-
-
-
-
-
Private Google Sheet
-
-
-
-
-
-
-
-
Public Google Sheet
-
-
-
-
-
-
-
-
Snowflake
-
-
-
-
-
-
-
-
Supabase
-
-
-
-
-
-
-
-
Tableau
-
-
-
-
-
-
-
-
TiDB
-
-
-
-
-
-
-
-
TigerGraph
-
-
-
diff --git a/data/kb/tutorials/databases/mongodb.md b/data/kb/tutorials/databases/mongodb.md
deleted file mode 100644
index 4afcc4624..000000000
--- a/data/kb/tutorials/databases/mongodb.md
+++ /dev/null
@@ -1,103 +0,0 @@
----
-title: Connect Streamlit to MongoDB
-slug: /knowledge-base/tutorials/databases/mongodb
----
-
-# Connect Streamlit to MongoDB
-
-## Introduction
-
-This guide explains how to securely access a **_remote_** MongoDB database from Streamlit Community Cloud. It uses the [PyMongo](https://github.com/mongodb/mongo-python-driver) library and Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-## Create a MongoDB Database
-
-
-
-If you already have a database that you want to use, feel free
-to [skip to the next step](#add-username-and-password-to-your-local-app-secrets).
-
-
-
-First, follow the official tutorials to [install MongoDB](https://docs.mongodb.com/guides/server/install/), [set up authentication](https://docs.mongodb.com/guides/server/auth/) (note down the username and password!), and [connect to the MongoDB instance](https://docs.mongodb.com/guides/server/drivers/). Once you are connected, open the `mongo` shell and enter the following two commands to create a collection with some example values:
-
-```sql
-use mydb
-db.mycollection.insertMany([{"name" : "Mary", "pet": "dog"}, {"name" : "John", "pet": "cat"}, {"name" : "Robert", "pet": "bird"}])
-```
-
-## Add username and password to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add the database information as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[mongo]
-host = "localhost"
-port = 27017
-username = "xxx"
-password = "xxx"
-```
-
-
-
-When copying your app secrets to Streamlit Community Cloud, be sure to replace the values of **host**, **port**, **username**, and **password** with those of your _remote_ MongoDB database!
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add PyMongo to your requirements file
-
-Add the [PyMongo](https://github.com/mongodb/mongo-python-driver) package to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-pymongo==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt the name of your database and collection.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-import pymongo
-
-# Initialize connection.
-# Uses st.cache_resource to only run once.
-@st.cache_resource
-def init_connection():
- return pymongo.MongoClient(**st.secrets["mongo"])
-
-client = init_connection()
-
-# Pull data from the collection.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def get_data():
- db = client.mydb
- items = db.mycollection.find()
- items = list(items) # make hashable for st.cache_data
- return items
-
-items = get_data()
-
-# Print results.
-for item in items:
- st.write(f"{item['name']} has a :{item['pet']}:")
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example data we created above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/mssql.md b/data/kb/tutorials/databases/mssql.md
deleted file mode 100644
index 1c734d3d7..000000000
--- a/data/kb/tutorials/databases/mssql.md
+++ /dev/null
@@ -1,193 +0,0 @@
----
-title: Connect Streamlit to Microsoft SQL Server
-slug: /knowledge-base/tutorials/databases/mssql
----
-
-# Connect Streamlit to Microsoft SQL Server
-
-## Introduction
-
-This guide explains how to securely access a **_remote_** Microsoft SQL Server database from Streamlit Community Cloud. It uses the [pyodbc](https://github.com/mkleehammer/pyodbc/wiki) library and Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-## Create an SQL Server database
-
-
-
-If you already have a remote database that you want to use, feel free
-to [skip to the next step](#add-username-and-password-to-your-local-app-secrets).
-
-
-
-First, follow the Microsoft documentation to install [SQL Server](https://docs.microsoft.com/en-gb/sql/sql-server/?view=sql-server-ver15) and the `sqlcmd` [Utility](https://docs.microsoft.com/en-gb/sql/tools/sqlcmd-utility?view=sql-server-ver15). They have detailed installation guides on how to:
-
-- [Install SQL Server on Windows](https://docs.microsoft.com/en-gb/sql/database-engine/install-windows/install-sql-server?view=sql-server-ver15)
-- [Install on Red Hat Enterprise Linux](https://docs.microsoft.com/en-gb/sql/linux/quickstart-install-connect-red-hat?view=sql-server-ver15)
-- [Install on SUSE Linux Enterprise Server](https://docs.microsoft.com/en-gb/sql/linux/quickstart-install-connect-suse?view=sql-server-ver15)
-- [Install on Ubuntu](https://docs.microsoft.com/en-gb/sql/linux/quickstart-install-connect-ubuntu?view=sql-server-ver15)
-- [Run on Docker](https://docs.microsoft.com/en-gb/sql/linux/quickstart-install-connect-docker?view=sql-server-ver15)
-- [Provision a SQL VM in Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/sql/provision-sql-server-linux-virtual-machine?toc=/sql/toc/toc.json)
-
-Once you have SQL Server installed, note down your SQL Server name, username, and password during setup.
-
-## Connect locally
-
-If you are connecting locally, use `sqlcmd` to connect to your new local SQL Server instance.
-
-1. In your terminal, run the following command:
-
- ```bash
- sqlcmd -S localhost -U SA -P ''
- ```
-
- As you are connecting locally, the SQL Server name is `localhost`, the username is `SA`, and the password is the one you provided during the SA account setup.
-
-2. You should see a **sqlcmd** command prompt `1>`, if successful.
-
-3. If you run into a connection failure, review Microsoft's connection troubleshooting recommendations for your OS ([Linux](https://docs.microsoft.com/en-gb/sql/linux/sql-server-linux-troubleshooting-guide?view=sql-server-ver15#connection) & [Windows](https://docs.microsoft.com/en-gb/sql/linux/sql-server-linux-troubleshooting-guide?view=sql-server-ver15#connection)).
-
-
-
-When connecting remotely, the SQL Server name is the machine name or IP address. You might also need to open the SQL Server TCP port (default 1433) on your firewall.
-
-
-
-### Create a SQL Server database
-
-By now, you have SQL Server running and have connected to it with `sqlcmd`! 🥳 Let's put it to use by creating a database containing a table with some example values.
-
-1. From the `sqlcmd` command prompt, run the following Transact-SQL command to create a test database `mydb`:
-
- ```sql
- CREATE DATABASE mydb
- ```
-
-2. To execute the above command, type `GO` on a new line:
-
- ```sql
- GO
- ```
-
-### Insert some data
-
-Next create a new table, `mytable`, in the `mydb` database with three columns and two rows.
-
-1. Switch to the new `mydb` database:
-
- ```sql
- USE mydb
- ```
-
-2. Create a new table with the following schema:
-
- ```sql
- CREATE TABLE mytable (name varchar(80), pet varchar(80))
- ```
-
-3. Insert some data into the table:
-
- ```sql
- INSERT INTO mytable VALUES ('Mary', 'dog'), ('John', 'cat'), ('Robert', 'bird')
- ```
-
-4. Type `GO` to execute the above commands:
-
- ```sql
- GO
- ```
-
-To end your **sqlcmd** session, type `QUIT` on a new line.
-
-### Add username and password to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add the SQL Server name, database name, username, and password as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-server = "localhost"
-database = "mydb"
-username = "SA"
-password = "xxx"
-```
-
-
-
-When copying your app secrets to Streamlit Community Cloud, be sure to replace the values of **server**, **database**, **username**, and **password** with those of your _remote_ SQL Server!
-
-And add this file to `.gitignore` and don't commit it to your GitHub repo.
-
-
-
-## Copy your app secrets to Streamlit Community Cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add pyodbc to your requirements file
-
-To connect to SQL Server _locally_ with Streamlit, you need to `pip install pyodbc`, in addition to the Microsoft ODBC driver you installed during the SQL Server installation.
-
-On _Streamlit Cloud_, we have built-in support for SQL Server. On popular demand, we directly added SQL Server tools including the ODBC drivers and the executables `sqlcmd` and `bcp` to the container image for Cloud apps, so you don't need to install them.
-
-All you need to do is add the [`pyodbc`](https://github.com/mkleehammer/pyodbc) Python package to your `requirements.txt` file, and you're ready to go! 🎈
-
-```bash
-# requirements.txt
-pyodbc==x.x.x
-```
-
-Replace `x.x.x` ☝️ with the version of pyodbc you want installed on Cloud.
-
-
-
-At this time, Streamlit Community Cloud does not support Azure Active Directory authentication. We will update this tutorial when we add support for Azure Active Directory.
-
-
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt `query` to use the name of your table.
-
-```python
-import streamlit as st
-import pyodbc
-
-# Initialize connection.
-# Uses st.cache_resource to only run once.
-@st.cache_resource
-def init_connection():
- return pyodbc.connect(
- "DRIVER={ODBC Driver 17 for SQL Server};SERVER="
- + st.secrets["server"]
- + ";DATABASE="
- + st.secrets["database"]
- + ";UID="
- + st.secrets["username"]
- + ";PWD="
- + st.secrets["password"]
- )
-
-conn = init_connection()
-
-# Perform query.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def run_query(query):
- with conn.cursor() as cur:
- cur.execute(query)
- return cur.fetchall()
-
-rows = run_query("SELECT * from mytable;")
-
-# Print results.
-for row in rows:
- st.write(f"{row[0]} has a :{row[1]}:")
-
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example table we created above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/mysql.md b/data/kb/tutorials/databases/mysql.md
deleted file mode 100644
index 0bba1572f..000000000
--- a/data/kb/tutorials/databases/mysql.md
+++ /dev/null
@@ -1,100 +0,0 @@
----
-title: Connect Streamlit to MySQL
-slug: /knowledge-base/tutorials/databases/mysql
----
-
-# Connect Streamlit to MySQL
-
-## Introduction
-
-This guide explains how to securely access a **_remote_** MySQL database from Streamlit Community Cloud. It uses [st.experimental_connection](/library/api-reference/connections/st.experimental_connection) and Streamlit's [Secrets management](/library/advanced-features/secrets-management). The below example code will **only work on Streamlit version >= 1.22**, when `st.experimental_connection` was added.
-
-## Create a MySQL database
-
-
-
-If you already have a database that you want to use, feel free
-to [skip to the next step](#add-username-and-password-to-your-local-app-secrets).
-
-
-
-First, follow [this tutorial](https://dev.mysql.com/doc/mysql-getting-started/en/) to install MySQL and start the MySQL server (note down the username and password!). Once your MySQL server is up and running, connect to it with the `mysql` client and enter the following commands to create a database and a table with some example values:
-
-```sql
-CREATE DATABASE pets;
-
-USE pets;
-
-CREATE TABLE mytable (
- name varchar(80),
- pet varchar(80)
-);
-
-INSERT INTO mytable VALUES ('Mary', 'dog'), ('John', 'cat'), ('Robert', 'bird');
-```
-
-## Add username and password to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Learn more about [Streamlit secrets management here](/library/advanced-features/secrets-management). Create this file if it doesn't exist yet and add the database name, user, and password of your MySQL server as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.mysql]
-dialect = "mysql"
-host = "localhost"
-port = 3306
-database = "xxx"
-username = "xxx"
-password = "xxx"
-```
-
-
-
-When copying your app secrets to Streamlit Community Cloud, be sure to replace the values of **host**, **port**, **database**, **username**, and **password** with those of your _remote_ MySQL database!
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add dependencies to your requirements file
-
-Add the [mysqlclient](https://github.com/PyMySQL/mysqlclient) and [SQLAlchemy](https://github.com/sqlalchemy/sqlalchemy) packages to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-mysqlclient==x.x.x
-SQLAlchemy==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt `query` to use the name of your table.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-# Initialize connection.
-conn = st.experimental_connection('mysql', type='sql')
-
-# Perform query.
-df = conn.query('SELECT * from mytable;', ttl=600)
-
-# Print results.
-for row in df.itertuples():
- st.write(f"{row.name} has a :{row.pet}:")
-```
-
-See `st.experimental_connection` above? This handles secrets retrieval, setup, query caching and retries. By default, `query()` results are cached without expiring. In this case, we set `ttl=600` to ensure the query result is cached for no longer than 10 minutes. You can also set `ttl=0` to disable caching. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example table we created above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/postgresql.md b/data/kb/tutorials/databases/postgresql.md
deleted file mode 100644
index edf5814ba..000000000
--- a/data/kb/tutorials/databases/postgresql.md
+++ /dev/null
@@ -1,107 +0,0 @@
----
-title: Connect Streamlit to PostgreSQL
-slug: /knowledge-base/tutorials/databases/postgresql
----
-
-# Connect Streamlit to PostgreSQL
-
-## Introduction
-
-This guide explains how to securely access a **_remote_** PostgreSQL database from Streamlit Community Cloud. It uses the [psycopg2](https://www.psycopg.org/) library and Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-## Create a PostgreSQL database
-
-
-
-If you already have a database that you want to use, feel free
-to [skip to the next step](#add-username-and-password-to-your-local-app-secrets).
-
-
-
-First, follow [this tutorial](https://www.tutorialspoint.com/postgresql/postgresql_environment.htm) to install PostgreSQL and create a database (note down the database name, username, and password!). Open the SQL Shell (`psql`) and enter the following two commands to create a table with some example values:
-
-```sql
-CREATE TABLE mytable (
- name varchar(80),
- pet varchar(80)
-);
-
-INSERT INTO mytable VALUES ('Mary', 'dog'), ('John', 'cat'), ('Robert', 'bird');
-```
-
-## Add username and password to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add the name, user, and password of your database as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[postgres]
-host = "localhost"
-port = 5432
-dbname = "xxx"
-user = "xxx"
-password = "xxx"
-```
-
-
-
-When copying your app secrets to Streamlit Community Cloud, be sure to replace the values of **host**, **port**, **dbname**, **user**, and **password** with those of your _remote_ PostgreSQL database!
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add psycopg2 to your requirements file
-
-Add the [psycopg2](https://www.psycopg.org/) package to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-psycopg2-binary==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt `query` to use the name of your table.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-import psycopg2
-
-# Initialize connection.
-# Uses st.cache_resource to only run once.
-@st.cache_resource
-def init_connection():
- return psycopg2.connect(**st.secrets["postgres"])
-
-conn = init_connection()
-
-# Perform query.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def run_query(query):
- with conn.cursor() as cur:
- cur.execute(query)
- return cur.fetchall()
-
-rows = run_query("SELECT * from mytable;")
-
-# Print results.
-for row in rows:
- st.write(f"{row[0]} has a :{row[1]}:")
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example table we created above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/private-gsheet.md b/data/kb/tutorials/databases/private-gsheet.md
deleted file mode 100644
index d94a74680..000000000
--- a/data/kb/tutorials/databases/private-gsheet.md
+++ /dev/null
@@ -1,151 +0,0 @@
----
-title: Connect Streamlit to a private Google Sheet
-slug: /knowledge-base/tutorials/databases/private-gsheet
----
-
-# Connect Streamlit to a private Google Sheet
-
-## Introduction
-
-This guide explains how to securely access a private Google Sheet from Streamlit Community Cloud. It uses the [gsheetsdb](https://github.com/betodealmeida/gsheets-db-api) library and Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-If you are fine with enabling link sharing for your Google Sheet (i.e. everyone with the link can view it), the guide [Connect Streamlit to a public Google Sheet](/knowledge-base/tutorials/databases/public-gsheet) shows a simpler method of doing this. If your Sheet contains sensitive information and you cannot enable link sharing, keep on reading.
-
-## Create a Google Sheet
-
-
-
-If you already have a database that you want to use, feel free
-to [skip to the next step](#enable-the-sheets-api).
-
-
-
-
-
-## Enable the Sheets API
-
-Programmatic access to Google Sheets is controlled through [Google Cloud Platform](https://cloud.google.com/). Create an account or sign in and head over to the [**APIs & Services** dashboard](https://console.cloud.google.com/apis/dashboard) (select or create a project if asked). As shown below, search for the Sheets API and enable it:
-
-
-
-
-
-
-
-## Create a service account & key file
-
-To use the Sheets API from Streamlit Community Cloud, you need a Google Cloud Platform service account (a special account type for programmatic data access). Go to the [**Service Accounts** page](https://console.cloud.google.com/iam-admin/serviceaccounts) and create an account with the **Viewer** permission (this will let the account access data but not change it):
-
-
-
-
-
-
-
-
-
-The button **CREATE SERVICE ACCOUNT** is gray, you don't have the correct permissions. Ask the admin of your Google Cloud project for help.
-
-
-
-After clicking **DONE**, you should be back on the service accounts overview. First, note down the email address of the account you just created (**important for next step!**). Then, create a JSON key file for the new account and download it:
-
-
-
-
-
-
-
-## Share the Google Sheet with the service account
-
-By default, the service account you just created cannot access your Google Sheet. To give it access, click on the **Share** button in the Google Sheet, add the email of the service account (noted down in step 2), and choose the correct permission (if you just want to read the data, **Viewer** is enough):
-
-
-
-
-
-
-## Add the key file to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add the URL of your Google Sheet plus the content of the key file you downloaded to it as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-private_gsheets_url = "https://docs.google.com/spreadsheets/d/12345/edit?usp=sharing"
-
-[gcp_service_account]
-type = "service_account"
-project_id = "xxx"
-private_key_id = "xxx"
-private_key = "xxx"
-client_email = "xxx"
-client_id = "xxx"
-auth_uri = "https://accounts.google.com/o/oauth2/auth"
-token_uri = "https://oauth2.googleapis.com/token"
-auth_provider_x509_cert_url = "https://www.googleapis.com/oauth2/v1/certs"
-client_x509_cert_url = "xxx"
-```
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add gsheetsdb to your requirements file
-
-Add the [gsheetsdb](https://github.com/betodealmeida/gsheets-db-api) package to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-gsheetsdb==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-from google.oauth2 import service_account
-from gsheetsdb import connect
-
-# Create a connection object.
-credentials = service_account.Credentials.from_service_account_info(
- st.secrets["gcp_service_account"],
- scopes=[
- "https://www.googleapis.com/auth/spreadsheets",
- ],
-)
-conn = connect(credentials=credentials)
-
-# Perform SQL query on the Google Sheet.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def run_query(query):
- rows = conn.execute(query, headers=1)
- rows = rows.fetchall()
- return rows
-
-sheet_url = st.secrets["private_gsheets_url"]
-rows = run_query(f'SELECT * FROM "{sheet_url}"')
-
-# Print results.
-for row in rows:
- st.write(f"{row.name} has a :{row.pet}:")
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example table we created above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/public-gsheet.md b/data/kb/tutorials/databases/public-gsheet.md
deleted file mode 100644
index a72d448b8..000000000
--- a/data/kb/tutorials/databases/public-gsheet.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-title: Connect Streamlit to a public Google Sheet
-slug: /knowledge-base/tutorials/databases/public-gsheet
----
-
-# Connect Streamlit to a public Google Sheet
-
-## Introduction
-
-This guide explains how to securely access a public Google Sheet from Streamlit Community Cloud. It uses the [pandas](https://pandas.pydata.org/) library and Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-This method requires you to enable link sharing for your Google Sheet. While the sharing link will not appear in your code (and actually acts as sort of a password!), someone with the link can get all the data in the Sheet. If you don't want this, follow the (more complicated) guide [Connect Streamlit to a private Google Sheet](private-gsheet).
-
-## Create a Google Sheet and turn on link sharing
-
-
-
-If you already have a Sheet that you want to access, feel free to [skip to the next
-step](#add-the-sheets-url-to-your-local-app-secrets).
-
-
-
-
-
-
-
-
-## Add the Sheets URL to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add the share link of your Google Sheet to it as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-public_gsheets_url = "https://docs.google.com/spreadsheets/d/xxxxxxx/edit#gid=0"
-```
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it.
-
-```python
-# streamlit_app.py
-
-import pandas as pd
-import streamlit as st
-
-# Read in data from the Google Sheet.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def load_data(sheets_url):
- csv_url = sheets_url.replace("/edit#gid=", "/export?format=csv&gid=")
- return pd.read_csv(csv_url)
-
-df = load_data(st.secrets["public_gsheets_url"])
-
-# Print results.
-for row in df.itertuples():
- st.write(f"{row.name} has a :{row.pet}:")
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example table we created above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/databases/snowflake.md b/data/kb/tutorials/databases/snowflake.md
deleted file mode 100644
index b680b916f..000000000
--- a/data/kb/tutorials/databases/snowflake.md
+++ /dev/null
@@ -1,213 +0,0 @@
----
-title: Connect Streamlit to Snowflake
-slug: /knowledge-base/tutorials/databases/snowflake
----
-
-# Connect Streamlit to Snowflake
-
-## Introduction
-
-This guide explains how to securely access a Snowflake database from Streamlit. It uses [st.experimental_connection](/library/api-reference/connections/st.experimental_connection), the [Snowpark Python](https://docs.snowflake.com/en/developer-guide/snowpark/python/index) library and Streamlit's [Secrets management](/library/advanced-features/secrets-management). The below example code **will only work on Streamlit version >= 1.22**, when `st.experimental_connection` was added.
-
-Skip to the bottom for information about [connecting using Snowflake Connector for Python](#using-the-snowflake-connector-for-python).
-
-## Create a Snowflake database
-
-
-
-If you already have a database that you want to use, feel free to [skip to the next step](#add-username-and-password-to-your-local-app-secrets).
-
-
-
-First, [sign up for Snowflake](https://signup.snowflake.com/) and log into the [Snowflake web interface](https://docs.snowflake.com/en/user-guide/connecting.html#logging-in-using-the-web-interface) (note down your username, password, and [account identifier](https://docs.snowflake.com/en/user-guide/admin-account-identifier.html)!):
-
-
-
-Enter the following queries into the SQL editor in the Worksheets page to create a database and a table with some example values:
-
-```sql
-CREATE DATABASE PETS;
-
-CREATE TABLE MYTABLE (
- NAME varchar(80),
- PET varchar(80)
-);
-
-INSERT INTO MYTABLE VALUES ('Mary', 'dog'), ('John', 'cat'), ('Robert', 'bird');
-
-SELECT * FROM MYTABLE;
-```
-
-Before you execute the queries, first determine which Snowflake UI / web interface you're using. The examples below use [Snowsight](https://docs.snowflake.com/en/user-guide/ui-snowsight). You can also use [Classic Console Worksheets](https://docs.snowflake.com/en/user-guide/ui-worksheet) or any other means of running Snowflake SQL statements.
-
-### Execute queries in a Worksheet
-
-To execute the queries in a Worksheet, highlight or select all the queries with your mouse, and click the play button in the top right corner.
-
-
-
-
-
-Be sure to highlight or select **all** the queries (lines 1-10) before clicking the play button.
-
-
-
-Once you have executed the queries, you should see a preview of the table in the **Results** panel at the bottom of the page. Additionally, you should see your newly created database and schema by expanding the accordion on the left side of the page. Lastly, the warehouse name is displayed on the button to the left of the **Share** button.
-
-
-
-Make sure to note down the name of your warehouse, database, and schema. ☝️
-
-## Install snowflake-snowpark-python
-
-You can find the instructions and prerequisites for installing `snowflake-snowpark-python` in the [Snowpark Developer Guide](https://docs.snowflake.com/en/developer-guide/snowpark/python/setup).
-
-```bash
-pip install "snowflake-snowpark-python[pandas]"
-```
-
-Particular prerequisites to highlight:
-
-- Currently, only python 3.8 is supported.
-- Ensure you have the correct pyarrow version installed for your version of `snowflake-snowpark-python`. When in doubt, try uninstalling pyarrow before installing snowflake-snowpark-python.
-
-## Add connection parameters to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app’s root directory. Learn more about [Streamlit secrets management here](/library/advanced-features/secrets-management). Create this file if it doesn’t exist yet and add your Snowflake username, password, [account identifier](https://docs.snowflake.com/en/user-guide/admin-account-identifier.html), and the name of your warehouse, database, and schema as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.snowpark]
-account = "xxx"
-user = "xxx"
-password = "xxx"
-role = "xxx"
-warehouse = "xxx"
-database = "xxx"
-schema = "xxx"
-client_session_keep_alive = true
-```
-
-If you created the database from the previous step, the names of your database and schema are `PETS` and `PUBLIC`, respectively. Streamlit will also use **Snowflake config and credentials** from a [SnowSQL config file](https://docs.snowflake.com/en/user-guide/snowsql-config#snowsql-config-file) if available.
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt the query to use the name of your table.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-# Initialize connection.
-conn = st.experimental_connection('snowpark')
-
-# Perform query.
-df = conn.query('SELECT * from mytable;', ttl=600)
-
-# Print results.
-for row in df.itertuples():
- st.write(f"{row.NAME} has a :{row.PET}:")
-```
-
-See `st.experimental_connection` above? This handles secrets retrieval, setup, query caching and retries. By default, `query()` results are cached without expiring. In this case, we set `ttl=600` to ensure the query result is cached for no longer than 10 minutes. You can also set `ttl=0` to disable caching. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example table we created above), your app should look like this:
-
-
-
-### Using a Snowpark Session
-
-The same [SnowparkConnection](/library/api-reference/connections/st.connections.snowparkconnection) used above also provides access to the [Snowpark Session](https://docs.snowflake.com/en/developer-guide/snowpark/reference/python/session.html) for DataFrame-style operations that run natively inside Snowflake. Using this approach, you can rewrite the app above as follows:
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-# Initialize connection.
-conn = st.experimental_connection('snowpark')
-
-# Load the table as a dataframe using the Snowpark Session.
-@st.cache_data
-def load_table():
- with conn.safe_session() as session:
- return session.table('mytable').to_pandas()
-
-df = load_table()
-
-# Print results.
-for row in df.itertuples():
- st.write(f"{row.NAME} has a :{row.PET}:")
-```
-
-This example uses `with conn.safe_session()` to provide thread safety. `conn.session` also works directly, but does not guarantee thread safety. If everything worked out (and you used the example table we created above), your app should look the same as the screenshot from the first example above.
-
-## Using the Snowflake Connector for Python
-
-In some cases, you may prefer to use the [Snowflake Connector for Python](https://docs.snowflake.com/en/developer-guide/python-connector/python-connector) instead of Snowpark Python. Streamlit supports this natively through the [SQLConnection](/library/api-reference/connections/st.connections.sqlconnection) and the [snowflake-sqlalchemy](https://docs.snowflake.com/en/developer-guide/python-connector/sqlalchemy) library.
-
-```bash
-pip install snowflake-sqlalchemy
-```
-
-Installing `snowflake-sqlalchemy` will also install all necessary dependencies.
-
-Configuring credentials follows the `SQLConnection` format which is slightly different. See the Snowflake SQLAlchemy [Configuration Parameters](https://docs.snowflake.com/en/developer-guide/python-connector/sqlalchemy#connection-parameters) documentation for more details.
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.snowflake]
-url = "snowflake://:@//?warehouse=&role="
-```
-
-Alternatively, specify connection parameters like `authenticator` or key pair authentication using `create_engine_kwargs`, as shown below.
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.snowflake]
-url = "snowflake://@/"
-
-[connections.snowflake.create_engine_kwargs.connect_args]
-authenticator = "externalbrowser"
-warehouse = "xxx"
-role = "xxx"
-client_session_keep_alive = true
-```
-
-Initializing and using the connection in your app is similar. Note that [SQLConnection.query()](/library/api-reference/connections/st.connections.sqlconnection#sqlconnectionquery) supports extra arguments like `params` and `chunksize` which may be useful for more advanced apps.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-# Initialize connection.
-conn = st.experimental_connection('snowflake', type='sql')
-
-# Perform query.
-df = conn.query('SELECT * from mytable;', ttl=600)
-
-# Print results.
-for row in df.itertuples():
- st.write(f"{row.name} has a :{row.pet}:")
-```
-
-If everything worked out (and you used the example table we created above), your app should look the same as the screenshot from the first example above.
-
-## Connecting to Snowflake from Community Cloud
-
-This tutorial assumes a local Streamlit app, however you can also connect to Snowflake from apps hosted in Community Cloud. The main additional steps are:
-
-- [Include information about dependencies](/streamlit-community-cloud/deploy-your-app/app-dependencies) using a `requirements.txt` file with `snowflake-snowpark-python` and any other dependencies.
-- [Add your secrets](/streamlit-community-cloud/deploy-your-app/secrets-management#deploy-an-app-and-set-up-secrets) to your Community Cloud app.
-- For apps using `snowflake-snowpark-python`, you should also ensure the app is [running on python 3.8](/streamlit-community-cloud/deploy-your-app#advanced-settings-for-deployment).
diff --git a/data/kb/tutorials/databases/supabase.md b/data/kb/tutorials/databases/supabase.md
deleted file mode 100644
index 1fc454408..000000000
--- a/data/kb/tutorials/databases/supabase.md
+++ /dev/null
@@ -1,143 +0,0 @@
----
-title: Connect Streamlit to Supabase
-slug: /knowledge-base/tutorials/databases/supabase
----
-
-# Connect Streamlit to Supabase
-
-## Introduction
-
-This guide explains how to securely access a Supabase instance from Streamlit Community Cloud. It uses the [Supabase Python Client Library](https://github.com/supabase-community/supabase-py) and Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management). Supabase is the open source Firebase alternative and is based on PostgreSQL.
-
-## Sign in to Supabase and create a project
-
-First, head over to [Supabase](https://app.supabase.io/) and sign up for a free account using your GitHub.
-
-
-
-
-
-
-Once you're signed in, you can create a project.
-
-
-
-
-
-
-Your screen should look like this once your project has been created:
-
-
-
-
-
-Make sure to note down your Project API Key and Project URL highlighted in the above screenshot. ☝️
-
-You will need these to connect to your Supabase instance from Streamlit.
-
-
-
-## Create a Supabase database
-
-Now that you have a project, you can create a database and populate it with some sample data. To do so, click on the **SQL editor** button on the same project page, followed by the **New query** button in the SQL editor.
-
-
-
-
-
-
-In the SQL editor, enter the following queries to create a database and a table with some example values:
-
-```sql
-CREATE TABLE mytable (
- name varchar(80),
- pet varchar(80)
-);
-
-INSERT INTO mytable VALUES ('Mary', 'dog'), ('John', 'cat'), ('Robert', 'bird');
-```
-
-Click **Run** to execute the queries. To verify that the queries were executed successfully, click on the **Table Editor** button on the left menu, followed by your newly created table `mytable`.
-
-
-
-
-
-
-With your Supabase database created, you can now connect to it from Streamlit!
-
-### Add Supabase Project URL and API key to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add the `supabase_url` and `supabase_key` here:
-
-```toml
-# .streamlit/secrets.toml
-
-supabase_url = "xxxx"
-supabase_key = "xxxx"
-```
-
-Replace `xxxx` above with your Project URL and API key from [Step 1](/knowledge-base/tutorials/databases/supabase#sign-in-to-supabase-and-create-a-project).
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add supabase to your requirements file
-
-Add the [`supabase`](https://github.com/supabase-community/supabase-py) Python Client Library to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-supabase==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-from supabase import create_client, Client
-
-# Initialize connection.
-# Uses st.cache_resource to only run once.
-@st.cache_resource
-def init_connection():
- url = st.secrets["supabase_url"]
- key = st.secrets["supabase_key"]
- return create_client(url, key)
-
-supabase = init_connection()
-
-# Perform query.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def run_query():
- return supabase.table("mytable").select("*").execute()
-
-rows = run_query()
-
-# Print results.
-for row in rows.data:
- st.write(f"{row['name']} has a :{row['pet']}:")
-
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example table we created above), your app should look like this:
-
-
-
-As Supabase uses PostgresSQL under the hood, you can also connect to Supabase by using the connection string Supabase provides under Settings > Databases. From there, you can refer to the [PostgresSQL tutorial](/knowledge-base/tutorials/databases/postgresql) to connect to your database.
diff --git a/data/kb/tutorials/databases/tableau.md b/data/kb/tutorials/databases/tableau.md
deleted file mode 100644
index 6a5f6e65b..000000000
--- a/data/kb/tutorials/databases/tableau.md
+++ /dev/null
@@ -1,149 +0,0 @@
----
-title: Connect Streamlit to Tableau
-slug: /knowledge-base/tutorials/databases/tableau
----
-
-# Connect Streamlit to Tableau
-
-## Introduction
-
-This guide explains how to securely access data on Tableau from Streamlit Community Cloud. It uses the [tableauserverclient](https://tableau.github.io/server-client-python/#) library and Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-## Create a Tableau site
-
-
-
-If you already have a database that you want to use, feel free
-to [skip to the next step](#create-personal-access-tokens).
-
-
-
-For simplicity, we are using the cloud version of Tableau here but this guide works equally well for self-hosted deployments. First, sign up for [Tableau Online](https://www.tableau.com/products/cloud-bi) or log in. Create a workbook or run one of the example workbooks under "Dashboard Starters".
-
-
-
-## Create personal access tokens
-
-While the Tableau API allows authentication via username and password, you should use [personal access tokens](https://help.tableau.com/current/server/en-us/security_personal_access_tokens.htm) for a production app.
-
-Go to your [Tableau Online homepage](https://online.tableau.com/), create an access token and note down the token name and secret.
-
-
-
-
-
-
-
-
-Personal access tokens will expire if not used after 15 consecutive days.
-
-
-
-## Add token to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Create this file if it doesn't exist yet and add your token, the site name you created during setup, and the URL of your Tableau server like below:
-
-```toml
-# .streamlit/secrets.toml
-
-[tableau]
-token_name = "xxx"
-token_secret = "xxx"
-server_url = "https://abc01.online.tableau.com/"
-site_id = "streamlitexample" # in your site's URL behind the server_url
-```
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add tableauserverclient to your requirements file
-
-Add the [tableauserverclient](https://tableau.github.io/server-client-python/#) package to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-tableauserverclient==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Note that this code just shows a few options of data you can get – explore the [tableauserverclient](https://tableau.github.io/server-client-python/#) library to find more!
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-import tableauserverclient as TSC
-
-
-# Set up connection.
-tableau_auth = TSC.PersonalAccessTokenAuth(
- st.secrets["tableau"]["token_name"],
- st.secrets["tableau"]["personal_access_token"],
- st.secrets["tableau"]["site_id"],
-)
-server = TSC.Server(st.secrets["tableau"]["server_url"], use_server_version=True)
-
-
-# Get various data.
-# Explore the tableauserverclient library for more options.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def run_query():
- with server.auth.sign_in(tableau_auth):
-
- # Get all workbooks.
- workbooks, pagination_item = server.workbooks.get()
- workbooks_names = [w.name for w in workbooks]
-
- # Get views for first workbook.
- server.workbooks.populate_views(workbooks[0])
- views_names = [v.name for v in workbooks[0].views]
-
- # Get image & CSV for first view of first workbook.
- view_item = workbooks[0].views[0]
- server.views.populate_image(view_item)
- server.views.populate_csv(view_item)
- view_name = view_item.name
- view_image = view_item.image
- # `view_item.csv` is a list of binary objects, convert to str.
- view_csv = b"".join(view_item.csv).decode("utf-8")
-
- return workbooks_names, views_names, view_name, view_image, view_csv
-
-workbooks_names, views_names, view_name, view_image, view_csv = run_query()
-
-
-# Print results.
-st.subheader("📓 Workbooks")
-st.write("Found the following workbooks:", ", ".join(workbooks_names))
-
-st.subheader("👁️ Views")
-st.write(
- f"Workbook *{workbooks_names[0]}* has the following views:",
- ", ".join(views_names),
-)
-
-st.subheader("🖼️ Image")
-st.write(f"Here's what view *{view_name}* looks like:")
-st.image(view_image, width=300)
-
-st.subheader("📊 Data")
-st.write(f"And here's the data for view *{view_name}*:")
-st.write(pd.read_csv(StringIO(view_csv)))
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out, your app should look like this (can differ based on your workbooks):
-
-
diff --git a/data/kb/tutorials/databases/tidb.md b/data/kb/tutorials/databases/tidb.md
deleted file mode 100644
index 0a2c9abca..000000000
--- a/data/kb/tutorials/databases/tidb.md
+++ /dev/null
@@ -1,152 +0,0 @@
----
-title: Connect Streamlit to TiDB
-slug: /knowledge-base/tutorials/databases/tidb
----
-
-# Connect Streamlit to TiDB
-
-## Introduction
-
-This guide explains how to securely access a **_remote_** TiDB database from Streamlit Community Cloud. It uses [st.experimental_connection](/library/api-reference/connections/st.experimental_connection) and Streamlit's [Secrets management](/library/advanced-features/secrets-management). The below example code will **only work on Streamlit version >= 1.22**, when `st.experimental_connection` was added.
-
-[TiDB](https://www.pingcap.com/tidb/) is an open-source, MySQL-compatible database that supports Hybrid Transactional and Analytical Processing (HTAP) workloads. [TiDB Cloud](https://www.pingcap.com/tidb-cloud/) is a fully managed cloud database service that simplifies the deployment and management of TiDB databases for developers.
-
-## Sign in to TiDB Cloud and create a cluster
-
-First, head over to [TiDB Cloud](https://tidbcloud.com/free-trial) and sign up for a free account, using either Google, GitHub, Microsoft or E-mail:
-
-
-
-Once you've signed in, you will already have a TiDB cluster:
-
-
-
-You can create more clusters if you want to. Click the cluster name to enter cluster overview page:
-
-
-
-Then click **Connect** to easily get the connection arguments to access the cluster. On the popup, click **Create password** to set the password.
-
-
-
-
-
-Make sure to note down the password. It won't be available on TiDB Cloud after this step.
-
-
-
-## Create a TiDB database
-
-
-
-If you already have a database that you want to use, feel free
-to [skip to the next step](#add-username-and-password-to-your-local-app-secrets).
-
-
-
-Once your TiDB cluster is up and running, connect to it with the `mysql` client(or with **Chat2Query** tab on the console) and enter the following commands to create a database and a table with some example values:
-
-```sql
-CREATE DATABASE pets;
-
-USE pets;
-
-CREATE TABLE mytable (
- name varchar(80),
- pet varchar(80)
-);
-
-INSERT INTO mytable VALUES ('Mary', 'dog'), ('John', 'cat'), ('Robert', 'bird');
-```
-
-## Add username and password to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app's root directory. Learn more about [Streamlit secrets management here](/library/advanced-features/secrets-management). Create this file if it doesn't exist yet and add host, username and password of your TiDB cluster as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.tidb]
-dialect = "mysql"
-host = ""
-port = 4000
-database = "pets"
-username = ""
-password = ""
-```
-
-
-
-When copying your app secrets to Streamlit Community Cloud, be sure to replace the values of **host**, **username** and **password** with those of your _remote_ TiDB cluster!
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on **Edit Secrets**. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add dependencies to your requirements file
-
-Add the [mysqlclient](https://github.com/PyMySQL/mysqlclient) and [SQLAlchemy](https://github.com/sqlalchemy/sqlalchemy) packages to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-mysqlclient==x.x.x
-SQLAlchemy==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt `query` to use the name of your table.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-# Initialize connection.
-conn = st.experimental_connection('tidb', type='sql')
-
-# Perform query.
-df = conn.query('SELECT * from mytable;', ttl=600)
-
-# Print results.
-for row in df.itertuples():
- st.write(f"{row.name} has a :{row.pet}:")
-```
-
-See `st.experimental_connection` above? This handles secrets retrieval, setup, query caching and retries. By default, `query()` results are cached without expiring. In this case, we set `ttl=600` to ensure the query result is cached for no longer than 10 minutes. You can also set `ttl=0` to disable caching. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example table we created above), your app should look like this:
-
-
-
-## Connect with PyMySQL
-
-Other than [mysqlclient](https://github.com/PyMySQL/mysqlclient), [PyMySQL](https://github.com/PyMySQL/PyMySQL) is another popular MySQL Python client. To use PyMySQL, first you need to adapt your requirements file:
-
-```bash
-# requirements.txt
-PyMySQL==x.x.x
-SQLAlchemy==x.x.x
-```
-
-Then adapt your secrets file:
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.tidb]
-dialect = "mysql"
-driver = "pymysql"
-host = ""
-port = 4000
-database = "pets"
-username = ""
-password = ""
-create_engine_kwargs = { connect_args = { ssl = { ca = "" }}}
-```
diff --git a/data/kb/tutorials/databases/tigergraph.md b/data/kb/tutorials/databases/tigergraph.md
deleted file mode 100644
index c8d90c7f8..000000000
--- a/data/kb/tutorials/databases/tigergraph.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-title: Connect Streamlit to TigerGraph
-slug: /knowledge-base/tutorials/databases/tigergraph
----
-
-# Connect Streamlit to TigerGraph
-
-## Introduction
-
-This guide explains how to securely access a TigerGraph database from Streamlit Community Cloud. It uses the [pyTigerGraph](https://pytigergraph.github.io/pyTigerGraph/GettingStarted/) library and Streamlit's [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-## Create a TigerGraph Cloud Database
-
-First, follow the official tutorials to create a TigerGraph instance in TigerGraph Cloud, either as a [blog](https://www.tigergraph.com/blog/getting-started-with-tigergraph-3-0/) or a [video](https://www.youtube.com/watch?v=NtNW2e8MfCQ). Note your username, password, and subdomain.
-
-For this tutorial, we will be using the COVID-19 starter kit. When setting up your solution, select the “COVID-19 Analysis" option.
-
-
-
-Once it is started, ensure your data is downloaded and queries are installed.
-
-
-
-## Add username and password to your local app secrets
-
-Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml` in your app’s root directory. Create this file if it doesn’t exist yet and add your TigerGraph Cloud instance username, password, graph name, and subdomain as shown below:
-
-```toml
-# .streamlit/secrets.toml
-
-[tigergraph]
-host = "https://xxx.i.tgcloud.io/"
-username = "xxx"
-password = "xxx"
-graphname = "xxx"
-```
-
-
-
-Add this file to `.gitignore` and don't commit it to your GitHub repo!
-
-
-
-## Copy your app secrets to the cloud
-
-As the `secrets.toml` file above is not committed to GitHub, you need to pass its content to your deployed app (on Streamlit Community Cloud) separately. Go to the [app dashboard](https://share.streamlit.io/) and in the app's dropdown menu, click on Edit Secrets. Copy the content of `secrets.toml` into the text area. More information is available at [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
-
-## Add PyTigerGraph to your requirements file
-
-Add the pyTigerGraph package to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
-
-```bash
-# requirements.txt
-pyTigerGraph==x.x.x
-```
-
-## Write your Streamlit app
-
-Copy the code below to your Streamlit app and run it. Make sure to adapt the name of your graph and query.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-import pyTigerGraph as tg
-
-# Initialize connection.
-conn = tg.TigerGraphConnection(**st.secrets["tigergraph"])
-conn.apiToken = conn.getToken(conn.createSecret())
-
-# Pull data from the graph by running the "mostDirectInfections" query.
-# Uses st.cache_data to only rerun when the query changes or after 10 min.
-@st.cache_data(ttl=600)
-def get_data():
- most_infections = conn.runInstalledQuery("mostDirectInfections")[0]["Answer"][0]
- return most_infections["v_id"], most_infections["attributes"]
-
-items = get_data()
-
-# Print results.
-st.title(f"Patient {items[0]} has the most direct infections")
-for key, val in items[1].items():
- st.write(f"Patient {items[0]}'s {key} is {val}.")
-```
-
-See `st.cache_data` above? Without it, Streamlit would run the query every time the app reruns (e.g. on a widget interaction). With `st.cache_data`, it only runs when the query changes or after 10 minutes (that's what `ttl` is for). Watch out: If your database updates more frequently, you should adapt `ttl` or remove caching so viewers always see the latest data. Learn more in [Caching](/library/advanced-features/caching).
-
-If everything worked out (and you used the example data we created above), your app should look like this:
-
-
diff --git a/data/kb/tutorials/deploy/docker.md b/data/kb/tutorials/deploy/docker.md
deleted file mode 100644
index 06274d943..000000000
--- a/data/kb/tutorials/deploy/docker.md
+++ /dev/null
@@ -1,265 +0,0 @@
----
-title: Deploy Streamlit using Docker
-slug: /knowledge-base/tutorials/deploy/docker
----
-
-# Deploy Streamlit using Docker
-
-## Introduction
-
-So you have an amazing app and you want to start sharing it with other people, what do you do? You have a few options. First, where do you want to run your Streamlit app, and how do you want to access it?
-
-- **On your corporate network** - Most corporate networks are closed to the outside world. You typically use a VPN to log onto your corporate network and access resources there. You could run your Streamlit app on a server in your corporate network for security reasons, to ensure that only folks internal to your company can access it.
-- **On the cloud** - If you'd like to access your Streamlit app from outside of a corporate network, or share your app with folks outside of your home network or laptop, you might choose this option. In this case, it'll depend on your hosting provider. We have [community-submitted guides](/knowledge-base/deploy/deploy-streamlit-heroku-aws-google-cloud) from Heroku, AWS, and other providers.
-
-Wherever you decide to deploy your app, you will first need to containerize it. This guide walks you through using Docker to deploy your app. If you prefer Kubernetes see [Deploy Streamlit using Kubernetes](/knowledge-base/tutorials/deploy/kubernetes).
-
-## Prerequisites
-
-1. [Install Docker Engine](#install-docker-engine)
-2. [Check network port accessibility](#check-network-port-accessibility)
-
-### Install Docker Engine
-
-If you haven't already done so, install [Docker](https://docs.docker.com/engine/install/#server) on your server. Docker provides `.deb` and `.rpm` packages from many Linux distributions, including:
-
-- [Debian](https://docs.docker.com/engine/install/debian/)
-- [Ubuntu](https://docs.docker.com/engine/install/ubuntu/)
-
-Verify that Docker Engine is installed correctly by running the `hello-world` Docker image:
-
-```bash
-sudo docker run hello-world
-```
-
-
-
-Follow Docker's official [post-installation steps for Linux](https://docs.docker.com/engine/install/linux-postinstall/) to run Docker as a non-root user, so that you don't have to preface the `docker` command with `sudo`.
-
-
-
-### Check network port accessibility
-
-As you and your users are behind your corporate VPN, you need to make sure all of you can access a certain network port. Let's say port `8501`, as it is the default port used by Streamlit. Contact your IT team and request access to port `8501` for you and your users.
-
-## Create a Dockerfile
-
-Docker builds images by reading the instructions from a `Dockerfile`. A `Dockerfile` is a text document that contains all the commands a user could call on the command line to assemble an image. Learn more in the [Dockerfile reference](https://docs.docker.com/engine/reference/builder/). The [docker build](https://docs.docker.com/engine/reference/commandline/build/) command builds an image from a `Dockerfile`. The [docker run](https://docs.docker.com/engine/reference/commandline/run/) command first creates a container over the specified image, and then starts it using the specified command.
-
-Here's an example `Dockerfile` that you can add to the root of your directory. i.e. in `/app/`
-
-```docker
-# app/Dockerfile
-
-FROM python:3.9-slim
-
-WORKDIR /app
-
-RUN apt-get update && apt-get install -y \
- build-essential \
- curl \
- software-properties-common \
- git \
- && rm -rf /var/lib/apt/lists/*
-
-RUN git clone https://github.com/streamlit/streamlit-example.git .
-
-RUN pip3 install -r requirements.txt
-
-EXPOSE 8501
-
-HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
-
-ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
-```
-
-### Dockerfile walkthrough
-
-Let’s walk through each line of the Dockerfile :
-
-1. A `Dockerfile` must start with a [`FROM`](https://docs.docker.com/engine/reference/builder/#from) instruction. It sets the [Base Image](https://docs.docker.com/glossary/#base-image) (think OS) for the container:
-
- ```docker
- FROM python:3.9-slim
- ```
-
- Docker has a number of official Docker base images based on various Linux distributions. They also have base images that come with language-specific modules such as [Python](https://hub.docker.com/_/python). The `python` images come in many flavors, each designed for a specific use case. Here, we use the `python:3.9-slim` image which is a lightweight image that comes with the latest version of Python 3.9.
-
-
-
- You can also use your own base image, provided the image you use contains a [supported version of Python](/knowledge-base/using-streamlit/sanity-checks#check-0-are-you-using-a-streamlit-supported-version-of-python) for Streamlit. There is no one-size-fits-all approach to using any specific base image, nor is there an official Streamlit-specific base image.
-
-
-
-2. The `WORKDIR` instruction sets the working directory for any `RUN`, `CMD`, `ENTRYPOINT`, `COPY` and `ADD` instructions that follow it in the `Dockerfile` . Let’s set it to `app/` :
-
- ```docker
- WORKDIR /app
- ```
-
-
-
- As mentioned in [Development flow](/library/get-started/main-concepts#development-flow), for Streamlit version 1.10.0 and higher, Streamlit apps cannot be run from the root directory of Linux distributions. Your main script should live in a directory other than the root directory. If you try to run a Streamlit app from the root directory, Streamlit will throw a `FileNotFoundError: [Errno 2] No such file or directory` error. For more information, see GitHub issue [#5239](https://github.com/streamlit/streamlit/issues/5239).
-
- If you are using Streamlit version 1.10.0 or higher, you must set the `WORKDIR` to a directory other than the root directory. For example, you can set the `WORKDIR` to `/app` as shown in the example `Dockerfile` above.
-
-
-3. Install `git` so that we can clone the app code from a remote repo:
-
- ```docker
- RUN apt-get update && apt-get install -y \
- build-essential \
- curl \
- software-properties-common \
- git \
- && rm -rf /var/lib/apt/lists/*
- ```
-
-4. Clone your code that lives in a remote repo to `WORKDIR`:
-
- a. If your code is in a public repo:
-
- ```docker
- RUN git clone https://github.com/streamlit/streamlit-example.git .
- ```
-
- Once cloned, the directory of `WORKDIR` will look like the following:
-
- ```bash
- app/
- - requirements.txt
- - streamlit_app.py
- ```
-
- where `requirements.txt` file contains all your [Python dependencies](https://docs.streamlit.io/streamlit-community-cloud/deploy-your-app/app-dependencies#add-python-dependencies). E.g
-
- ```
- altair
- pandas
- streamlit
- ```
-
- and `streamlit_app.py` is your main script. E.g.
-
- ```python
- from collections import namedtuple
- import altair as alt
- import math
- import pandas as pd
- import streamlit as st
-
- """
- # Welcome to Streamlit!
-
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:
-
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
- forums](https://discuss.streamlit.io).
-
- In the meantime, below is an example of what you can do with just a few lines of code:
- """
-
- with st.echo(code_location='below'):
- total_points = st.slider("Number of points in spiral", 1, 5000, 2000)
- num_turns = st.slider("Number of turns in spiral", 1, 100, 9)
-
- Point = namedtuple('Point', 'x y')
- data = []
-
- points_per_turn = total_points / num_turns
-
- for curr_point_num in range(total_points):
- curr_turn, i = divmod(curr_point_num, points_per_turn)
- angle = (curr_turn + 1) * 2 * math.pi * i / points_per_turn
- radius = curr_point_num / total_points
- x = radius * math.cos(angle)
- y = radius * math.sin(angle)
- data.append(Point(x, y))
-
- st.altair_chart(alt.Chart(pd.DataFrame(data), height=500, width=500)
- .mark_circle(color='#0068c9', opacity=0.5)
- .encode(x='x:Q', y='y:Q'))
- ```
-
- b. If your code is in a private repo, please read [Using SSH to access private data in builds](https://docs.docker.com/develop/develop-images/build_enhancements/#using-ssh-to-access-private-data-in-builds) and modify the Dockerfile accordingly -- to install an SSH client, download the public key for [github.com](https://github.com), and clone your private repo. If you use an alternative VCS such as GitLab or Bitbucket, please consult the documentation for that VCS on how to copy your code to the `WORKDIR` of the Dockerfile.
-
- c. If your code lives in the same directory as the Dockerfile, copy all your app files from your server into the container, including `streamlit_app.py`, `requirements.txt`, etc, by replacing the `git clone` line with:
-
- ```docker
- COPY . .
- ```
-
- More generally, the idea is copy your app code from wherever it may live on your server into the container. If the code is not in the same directory as the Dockerfile, modify the above command to include the path to the code.
-
-5. Install your app’s [Python dependencies](/streamlit-community-cloud/deploy-your-app/app-dependencies#add-python-dependencies) from the cloned `requirements.txt` in the container:
-
- ```docker
- RUN pip3 install -r requirements.txt
- ```
-
-6. The [`EXPOSE`](https://docs.docker.com/engine/reference/builder/#expose) instruction informs Docker that the container listens on the specified network ports at runtime. Your container needs to listen to Streamlit’s (default) port 8501:
-
- ```docker
- EXPOSE 8501
- ```
-
-7. The [`HEALTHCHECK`](https://docs.docker.com/engine/reference/builder/#expose) instruction tells Docker how to test a container to check that it is still working. Your container needs to listen to Streamlit’s (default) port 8501:
-
- ```docker
- HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
- ```
-
-8. An [`ENTRYPOINT`](https://docs.docker.com/engine/reference/builder/#entrypoint) allows you to configure a container that will run as an executable. Here, it also contains the entire `streamlit run` command for your app, so you don’t have to call it from the command line:
-
- ```docker
- ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
- ```
-
-## Build a Docker image
-
-The [`docker build`](https://docs.docker.com/engine/reference/commandline/build/) command builds an image from a `Dockerfile` . Run the following command from the `app/` directory on your server to build the image:
-
-```docker
-docker build -t streamlit .
-```
-
-The `-t` flag is used to tag the image. Here, we have tagged the image `streamlit`. If you run:
-
-```docker
-docker images
-```
-
-You should see a `streamlit` image under the REPOSITORY column. For example:
-
-```
-REPOSITORY TAG IMAGE ID CREATED SIZE
-streamlit latest 70b0759a094d About a minute ago 1.02GB
-```
-
-## Run the Docker container
-
-Now that you have built the image, you can run the container by executing:
-
-```docker
-docker run -p 8501:8501 streamlit
-```
-
-The `-p` flag publishes the container’s port 8501 to your server’s 8501 port.
-
-If all went well, you should see an output similar to the following:
-
-```
-docker run -p 8501:8501 streamlit
-
- You can now view your Streamlit app in your browser.
-
- URL: http://0.0.0.0:8501
-```
-
-To view your app, users can browse to `http://0.0.0.0:8501` or `http://localhost:8501`
-
-
-
-Based on your server's network configuration, you could map to port 80/443 so that users can view your app using the server IP or hostname. For example: `http://your-server-ip:80` or `http://your-hostname:443`.
-
-
diff --git a/data/kb/tutorials/deploy/index.md b/data/kb/tutorials/deploy/index.md
deleted file mode 100644
index 8b43678bb..000000000
--- a/data/kb/tutorials/deploy/index.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: Deploy Streamlit apps
-slug: /knowledge-base/tutorials/deploy
----
-
-# Deploy Streamlit apps
-
-This sections contains step-by-step guides on how to deploy Streamlit apps to various cloud platforms and services. We have deployment guides for:
-
-
-
-
-
-
-
-
-### Settings
-
-With the "**Settings**" option, you can control the appearance of your app while it is running. If viewing the app locally, you can set how your app responds to changes in your source code. See more about development flow in [Main concepts](/library/get-started/main-concepts#development-flow). You can also force your app to appear in wide mode, even if not set within the script using [`st.set_page_config`](/library/api-reference/utilities/st.set_page_config).
-
-
-
-
-
-#### Theme settings
-
-After clicking "**Settings**" from the app menu, you can choose between "**Light**", "**Dark**", or "**Use system setting**" for the app's base theme. Click on "**Edit active theme**" to modify the theme, color-by-color.
-
-
-
-
-
-
-
-
-
-
-
-### Print
-
-Click "**Print**" to open a print dialog. This option uses your browser's built-in print-to-pdf function.
-
-
-
-
-
-### Record a screencast
-
-You can easily make screen recordings right from your app! Screen recording is supported in the latest versions of Chrome, Edge, and Firefox. Ensure your browser is up-to-date for compatibility. Depending on your current settings, you may need to grant permission to your browser to record your screen or to use your microphone if recording a voiceover.
-
-1. While viewing your app, open the app menu from the upper-right corner.
-2. Click "**Record a screencast**."
-
-
-
-
-
-3. If you want to record audio through your microphone, check "**Also record audio**."
-4. Click "**Start recording**." (You may be prompted by your OS to permit your browser to record your screen or use your microphone.)
-
-
-
-
-
-5. Select which tab, window, or monitor you want to record from the listed options. The interface will vary depending on your browser.
-
-
-
-
-
-6. Click "**Share**."
-
-
-
-
-
-7. While recording, you will see a red circle on your app's tab and on the app menu icon. If you want to cancel the recording, click "**Stop sharing**" at the bottom of your app.
-
-
-
-
-
-8. When you are done recording, press "**Esc**" on your keyboard or click "**Stop recording**" from your app's menu.
-
-
-
-
-
-9. Follow your browser's instructions to save your recording. Your saved recording will be available where your browser saves downloads.
-
-The whole process looks like this:
-
-
-
-
-
-### About
-
-You can conveniently check what version of Streamlit is running from the "**About**" option. Developers also have the option to customize the message shown here using [`st.set_page_config`](/library/api-reference/utilities/st.set_page_config).
-
-
-
-
-
-## Developer options
-
-By default, developer options only show when viewing an app locally or when viewing a Community Cloud app while logged in with administrative permission. You can [customize the menu](#customize-the-menu) if you want to make these options available for all users.
-
-### Clear cache
-
-Reset your app's cache by clicking "**Clear cache**" from the app's menu or by pressing "**C**" on your keyboard while not focused on an input element. This will remove all cached entries for [`@st.cache_data`](/library/api-reference/performance/st.cache_data) and [`@st.cache_resource`](/library/api-reference/performance/st.cache_resource).
-
-
-
-
-
-### Deploy this app
-
-If you are running an app locally from within a git repo, you can deploy your app to Streamlit Community Cloud in a few easy clicks! Make sure your work has been pushed to your online GitHub repository before beginning. For the greatest convenience, make sure you have already created your [Community Cloud account](/streamlit-community-cloud/get-started/create-your-account) and are signed in. Click "**Deploy this app**" to be taken directly to Community Cloud's "Deploy an app" page. Your app's repository, branch, and file name will be prefilled to match your current app! Learn more about [deploying an app](/streamlit-community-cloud/deploy-your-app) on Streamlit Community Cloud.
-
-
-
-
-
-## Customize the menu
-
-Using `client.toolbarMode` in your app's [configuration](/library/advanced-features/configuration), you can make the app menu appear in the following ways:
-
-- `"developer"` — Show the developer options to all viewers.
-- `"viewer"` — Hide the developer options from all viewers.
-- `"minimal"` — Show only those options set externally. These can be options declared through [`st.set_page_config`](/library/api-reference/utilities/st.set_page_config) or options populated through Streamlit Community Cloud.
-- `"auto"` — This is the default and will show the developer options when accessed through localhost or through Streamlit Community Cloud when logged into an administrative account for the app. Otherwise, the developer options will not show.
diff --git a/data/library/advanced-features/button-behavior-and-examples.md b/data/library/advanced-features/button-behavior-and-examples.md
deleted file mode 100644
index 7fddcd50a..000000000
--- a/data/library/advanced-features/button-behavior-and-examples.md
+++ /dev/null
@@ -1,421 +0,0 @@
----
-title: Button behavior and examples
-slug: /library/advanced-features/button-behavior-and-examples
----
-
-# Button behavior and examples
-
-## Summary
-
-Buttons created with [`st.button`](/library/api-reference/widgets/st.button) do not retain state. They return `True` on the script rerun resulting from their click and immediately return to `False` on the next script rerun. If a displayed element is nested inside `if st.button('Click me'):`, the element will be visible when the button is clicked and disappear as soon as the user takes their next action. This is because the script reruns and the button return value becomes `False`.
-
-In this guide, we will illustrate the use of buttons and explain common misconceptions. Read on to see a variety of examples that expand on `st.button` using [`st.session_state`](/library/api-reference/session-state). [Anti-patterns](#anti-patterns) are included at the end. Go ahead and pull up your favorite code editor so you can `streamlit run` the examples as you read. Check out Streamlit's [Main concepts](/library/get-started/main-concepts) if you haven't run your own Streamlit scripts yet.
-
-## When to use `if st.button()`
-
-When code is conditioned on a button's value, it will execute once in response to the button being clicked and not again (until the button is clicked again).
-
-Good to nest inside buttons:
-
-- Transient messages that immediately disappear.
-- Once-per-click processes that saves data to session state, a file, or
- a database.
-
-Bad to nest inside buttons:
-
-- Displayed items that should persist as the user continues.
-- Other widgets which cause the script to rerun when used.
-- Processes that neither modify session state nor write to a file/database.\*
-
-\* This can be appropriate when disposable results are desired. If you
-have a "Validate" button, that could be a process conditioned directly on a
-button. It could be used to create an alert to say 'Valid' or 'Invalid' with no
-need to keep that info.
-
-## Common logic with buttons
-
-### Show a temporary message with a button
-
-If you want to give the user a quick button to check if an entry is valid, but not keep that check displayed as the user continues.
-
-In this example, a user can click a button to check if their `animal` string is in the `animal_shelter` list. When the user clicks "**Check availability**" they will see "We have that animal!" or "We don't have that animal." If they change the animal in [`st.text_input`](/library/api-reference/widgets/st.text_input), the script reruns and the message disappears until they click "**Check availability**" again.
-
-```python
-import streamlit as st
-
-animal_shelter = ['cat', 'dog', 'rabbit', 'bird']
-
-animal = st.text_input('Type an animal')
-
-if st.button('Check availability'):
- have_it = animal.lower() in animal_shelter
- 'We have that animal!' if have_it else 'We don\'t have that animal.'
-```
-
-Note: The above example uses [magic](/library/api-reference/write-magic/magic) to render the message on the frontend.
-
-### Stateful button
-
-If you want a clicked button to continue to be `True`, create a value in `st.session_state` and use the button to set that value to `True` in a callback.
-
-```python
-import streamlit as st
-
-if 'clicked' not in st.session_state:
- st.session_state.clicked = False
-
-def click_button():
- st.session_state.clicked = True
-
-st.button('Click me', on_click=click_button)
-
-if st.session_state.clicked:
- # The message and nested widget will remain on the page
- st.write('Button clicked!')
- st.slider('Select a value')
-```
-
-### Toggle button
-
-If you want a button to work like a toggle switch, consider using [`st.checkbox`](/library/api-reference/widgets/st.checkbox). Otherwise, you can use a button with a callback function to reverse a boolean value saved in `st.session_state`.
-
-In this example, we use `st.button` to toggle another widget on and off. By displaying [`st.slider`](/library/api-reference/widgets/st.slider) conditionally on a value in `st.session_state`, the user can interact with the slider without it disappearing.
-
-```python
-import streamlit as st
-
-if 'button' not in st.session_state:
- st.session_state.button = False
-
-def click_button():
- st.session_state.button = not st.session_state.button
-
-st.button('Click me', on_click=click_button)
-
-if st.session_state.button:
- # The message and nested widget will remain on the page
- st.write('Button is on!')
- st.slider('Select a value')
-else:
- st.write('Button is off!')
-```
-
-Alternatively, you can use the value in `st.session_state` on the slider's `disabled` parameter.
-
-```python
-import streamlit as st
-
-if 'button' not in st.session_state:
- st.session_state.button = False
-
-def click_button():
- st.session_state.button = not st.session_state.button
-
-st.button('Click me', on_click=click_button)
-
-st.slider('Select a value', disabled=st.session_state.button)
-```
-
-### Buttons to continue or control stages of a process
-
-Another alternative to nesting content inside a button is to use a value in `st.session_state` that designates the "step" or "stage" of a process. In this example, we have four stages in our script:
-
-0. Before the user begins.
-1. User enters their name.
-2. User chooses a color.
-3. User gets a thank-you message.
-
-A button at the beginning advances the stage from 0 to 1. A button at the end resets the stage from 3 to 0. The other widgets used in stage 1 and 2 have callbacks to set the stage. If you have a process with dependant steps and want to keep previous stages visible, such a callback forces a user to retrace subsequent stages if they change an earlier widget.
-
-```python
-import streamlit as st
-
-if 'stage' not in st.session_state:
- st.session_state.stage = 0
-
-def set_state(i):
- st.session_state.stage = i
-
-if st.session_state.stage == 0:
- st.button('Begin', on_click=set_state, args=[1])
-
-if st.session_state.stage >= 1:
- name = st.text_input('Name', on_change=set_state, args=[2])
-
-if st.session_state.stage >= 2:
- st.write(f'Hello {name}!')
- color = st.selectbox(
- 'Pick a Color',
- [None, 'red', 'orange', 'green', 'blue', 'violet'],
- on_change=set_state, args=[3]
- )
- if color is None:
- set_state(2)
-
-if st.session_state.stage >= 3:
- st.write(f':{color}[Thank you!]')
- st.button('Start Over', on_click=set_state, args=[0])
-```
-
-### Buttons to modify `st.session_state`
-
-If you modify `st.session_state` inside of a button, you must consider where that button is within the script.
-
-#### A slight problem
-
-In this example, we access `st.session_state.name` both before and after the buttons which modify it. When a button ("**Jane**" or "**John**") is clicked, the script reruns. The info displayed before the buttons lags behind the info written after the button. The data in `st.session_state` before the button is not updated. When the script executes the button function, that is when the conditional code to update `st.session_state` creates the change. Thus, this change is reflected after the button.
-
-```python
-import streamlit as st
-import pandas as pd
-
-if 'name' not in st.session_state:
- st.session_state['name'] = 'John Doe'
-
-st.header(st.session_state['name'])
-
-if st.button('Jane'):
- st.session_state['name'] = 'Jane Doe'
-
-if st.button('John'):
- st.session_state['name'] = 'John Doe'
-
-st.header(st.session_state['name'])
-```
-
-#### Logic used in a callback
-
-Callbacks are a clean way to modify `st.session_state`. Callbacks are executed as a prefix to the script rerunning, so the position of the button relative to accessing data is not important.
-
-```python
-import streamlit as st
-import pandas as pd
-
-if 'name' not in st.session_state:
- st.session_state['name'] = 'John Doe'
-
-def change_name(name):
- st.session_state['name'] = name
-
-st.header(st.session_state['name'])
-
-st.button('Jane', on_click=change_name, args=['Jane Doe'])
-st.button('John', on_click=change_name, args=['John Doe'])
-
-st.header(st.session_state['name'])
-```
-
-#### Logic nested in a button with a rerun
-
-Although callbacks are often preferred to avoid extra reruns, our first 'John Doe'/'Jane Doe' example can be modified by adding [`st.experimental_rerun`](/library/api-reference/control-flow/st.experimental_rerun) instead. If you need to acces data in `st.session_state` before the button that modifies it, you can include `st.experimental_rerun` to rerun the script after the change has been committed. This means the script will rerun twice when a button is clicked.
-
-```python
-import streamlit as st
-import pandas as pd
-
-if 'name' not in st.session_state:
- st.session_state['name'] = 'John Doe'
-
-st.header(st.session_state['name'])
-
-if st.button('Jane'):
- st.session_state['name'] = 'Jane Doe'
- st.experimental_rerun()
-
-if st.button('John'):
- st.session_state['name'] = 'John Doe'
- st.experimental_rerun()
-
-st.header(st.session_state['name'])
-```
-
-### Buttons to modify or reset other widgets
-
-When a button is used to modify or reset another widget, it is the same as the above examples to modify `st.session_state`. However, an extra consideration exists: you cannot modify a key-value pair in `st.session_state` if the widget with that key has already been rendered on the page for the current script run.
-
-
-
-Don't do this!
-
-```python
-import streamlit as st
-
-st.text_input('Name', key='name')
-
-# These buttons will error because their nested code changes
-# a widget's state after that widget within the script.
-if st.button('Clear name'):
- st.session_state.name = ''
-if st.button('Streamlit!'):
- set_name('Streamlit')
-```
-
-
-
-#### Option 1: Use a key for the button and put the logic before the widget
-
-If you assign a key to a button, you can condition code on a button's state by using its value in `st.session_state`. This means that logic depending on your button can be in your script before that button. In the following example, we use the `.get()` method on `st.session_state` because the keys for the buttons will not exist when the script runs for the first time. The `.get()` method will return `False` if it can't find the key. Otherwise, it will return the value of the key.
-
-```python
-import streamlit as st
-
-# Use the get method since the keys won't be in session_state
-# on the first script run
-if st.session_state.get('clear'):
- st.session_state['name'] = ''
-if st.session_state.get('streamlit'):
- st.session_state['name'] = 'Streamlit'
-
-st.text_input('Name', key='name')
-
-st.button('Clear name', key='clear')
-st.button('Streamlit!', key='streamlit')
-```
-
-#### Option 2: Use a callback
-
-```python
-import streamlit as st
-
-st.text_input('Name', key='name')
-
-def set_name(name):
- st.session_state.name = name
-
-st.button('Clear name', on_click=set_name, args=[''])
-st.button('Streamlit!', on_click=set_name, args=['Streamlit'])
-```
-
-#### Option 3: Use containers
-
-By using [`st.container`](/library/api-reference/layout/st.container) you can have widgets appear in different orders in your script and frontend view (webpage).
-
-```python
-import streamlit as st
-
-begin = st.container()
-
-if st.button('Clear name'):
- st.session_state.name = ''
-if st.button('Streamlit!'):
- st.session_state.name = ('Streamlit')
-
-# The widget is second in logic, but first in display
-begin.text_input('Name', key='name')
-```
-
-### Buttons to add other widgets dynamically
-
-When dynamically adding widgets to the page, make sure to use an index to keep the keys unique and avoid a `DuplicateWidgetID` error. In this example, we define a function `display_input_row` which renders a row of widgets. That function accepts an `index` as a parameter. The widgets rendered by `display_input_row` use `index` within their keys so that `dispaly_input_row` can be executed multiple times on a single script rerun without repeating any widget keys.
-
-```python
-import streamlit as st
-
-def display_input_row(index):
- left, middle, right = st.columns(3)
- left.text_input('First', key=f'first_{index}')
- middle.text_input('Middle', key=f'middle_{index}')
- right.text_input('Last', key=f'last_{index}')
-
-if 'rows' not in st.session_state:
- st.session_state['rows'] = 0
-
-def increase_rows():
- st.session_state['rows'] += 1
-
-st.button('Add person', on_click=increase_rows)
-
-for i in range(st.session_state['rows']):
- display_input_row(i)
-
-# Show the results
-st.subheader('People')
-for i in range(st.session_state['rows']):
- st.write(
- f'Person {i+1}:',
- st.session_state[f'first_{i}'],
- st.session_state[f'middle_{i}'],
- st.session_state[f'last_{i}']
- )
-```
-
-### Buttons to handle expensive or file-writing processes
-
-When you have expensive processes, set them to run upon clicking a button and save the results into `st.session_state`. This allows you to keep accessing the results of the process without re-executing it unnecessarily. This is especially helpful for processes that save to disk or write to a database. In this example, we have an `expensive_process` that depends on two parameters: `option` and `add`. Functionally, `add` changes the output, but `option` does not—`option` is there to provide a parameter
-
-```python
-import streamlit as st
-import pandas as pd
-import time
-
-def expensive_process(option, add):
- with st.spinner('Processing...'):
- time.sleep(5)
- df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7, 8, 9]}) + add
- return (df, add)
-
-cols = st.columns(2)
-option = cols[0].selectbox('Select a number', options=['1', '2', '3'])
-add = cols[1].number_input('Add a number', min_value=0, max_value=10)
-
-if 'processed' not in st.session_state:
- st.session_state.processed = {}
-
-# Process and save results
-if st.button('Process'):
- result = expensive_process(option, add)
- st.session_state.processed[option] = result
-
-if option in st.session_state.processed:
- st.write(f'Option {option} processed with add {add}')
- st.write(st.session_state.processed[option][0])
-```
-
-Astute observers may think, "This feels a little like caching." We are only saving results relative to one parameter, but the pattern could easily be expanded to save results relative to both parameters. In that sense, yes, it has some similarities to caching, but also some important differences. When you save results in `st.session_state`, the results are only available to the current user in their current session. If you use [`st.cache_data`](/library/api-reference/performance/st.cache_data) instead, the results are available to all users across all sessions. Furthermore, if you want to update a saved result, you have to clear all saved results for that function to do so.
-
-## Anti-patterns
-
-Here are some simplified examples of how buttons can go wrong. Be on the lookout for these common mistakes.
-
-### Buttons nested inside buttons
-
-```python
-import streamlit as st
-
-if st.button('Button 1'):
- st.write('Button 1 was clicked')
- if st.button('Button 2'):
- # This will never be executed.
- st.write('Button 2 was clicked')
-```
-
-### Other widgets nested inside buttons
-
-```python
-import streamlit as st
-
-if st.button('Sign up'):
- name = st.text_input('Name')
-
- if name:
- # This will never be executed.
- st.success(f'Welcome {name}')
-```
-
-### Nesting a process inside a button without saving to session state
-
-```python
-import streamlit as st
-import pandas as pd
-
-file = st.file_uploader("Upload a file", type="csv")
-
-if st.button('Get data'):
- df = pd.read_csv(file)
- # This display will go away with the user's next action.
- st.write(df)
-
-if st.button('Save'):
- # This will always error.
- df.to_csv('data.csv')
-```
diff --git a/data/library/advanced-features/caching.md b/data/library/advanced-features/caching.md
deleted file mode 100644
index 32e73b721..000000000
--- a/data/library/advanced-features/caching.md
+++ /dev/null
@@ -1,888 +0,0 @@
----
-title: Caching
-slug: /library/advanced-features/caching
----
-
-# Caching
-
-Streamlit runs your script from top to bottom at every user interaction or code change. This execution model makes development super easy. But it comes with two major challenges:
-
-1. Long-running functions run again and again, which slows down your app.
-2. Objects get recreated again and again, which makes it hard to persist them across reruns or sessions.
-
-But don't worry! Streamlit lets you tackle both issues with its built-in caching mechanism. Caching stores the results of slow function calls, so they only need to run once. This makes your app much faster and helps with persisting objects across reruns.
-
-
-
-1. [Minimal example](#minimal-example)
-2. [Basic usage](#basic-usage)
-3. [Advanced usage](#advanced-usage)
-4. [Migrating from st.cache](#migrating-from-stcache)
-
-
-
-## Minimal example
-
-To cache a function in Streamlit, you must decorate it with one of two decorators (`st.cache_data` or `st.cache_resource`):
-
-```python
-@st.cache_data
-def long_running_function(param1, param2):
- return …
-```
-
-In this example, decorating `long_running_function` with `@st.cache_data` tells Streamlit that whenever the function is called, it checks two things:
-
-1. The values of the input parameters (in this case, `param1` and `param2`).
-2. The code inside the function.
-
-If this is the first time Streamlit sees these parameter values and function code, it runs the function and stores the return value in a cache. The next time the function is called with the same parameters and code (e.g., when a user interacts with the app), Streamlit will skip executing the function altogether and return the cached value instead. During development, the cache updates automatically as the function code changes, ensuring that the latest changes are reflected in the cache.
-
-As mentioned, there are two caching decorators:
-
-- `st.cache_data` is the recommended way to cache computations that return data: loading a DataFrame from CSV, transforming a NumPy array, querying an API, or any other function that returns a serializable data object (str, int, float, DataFrame, array, list, …). It creates a new copy of the data at each function call, making it safe against [mutations and race conditions](#mutation-and-concurrency-issues). The behavior of `st.cache_data` is what you want in most cases – so if you're unsure, start with `st.cache_data` and see if it works!
-- `st.cache_resource` is the recommended way to cache global resources like ML models or database connections – unserializable objects that you don't want to load multiple times. Using it, you can share these resources across all reruns and sessions of an app without copying or duplication. Note that any mutations to the cached return value directly mutate the object in the cache (more details below).
-
-
-
-## Basic usage
-
-### st.cache_data
-
-`st.cache_data` is your go-to command for all functions that return data – whether DataFrames, NumPy arrays, str, int, float, or other serializable types. It's the right command for almost all use cases!
-
-#### Usage
-
-
-
-Let's look at an example of using `st.cache_data`. Suppose your app loads the [Uber ride-sharing dataset](https://github.com/plotly/datasets/blob/master/uber-rides-data1.csv) – a CSV file of 50 MB – from the internet into a DataFrame:
-
-```python
-def load_data(url):
- df = pd.read_csv(url) # 👈 Download the data
- return df
-
-df = load_data("https://github.com/plotly/datasets/raw/master/uber-rides-data1.csv")
-st.dataframe(df)
-
-st.button("Rerun")
-```
-
-Running the `load_data` function takes 2 to 30 seconds, depending on your internet connection. (Tip: if you are on a slow connection, use [this 5 MB dataset instead](https://github.com/plotly/datasets/blob/master/26k-consumer-complaints.csv)). Without caching, the download is rerun each time the app is loaded or with user interaction. Try it yourself by clicking the button we added! Not a great experience… 😕
-
-Now let's add the `@st.cache_data` decorator on `load_data`:
-
-```python
-@st.cache_data # 👈 Add the caching decorator
-def load_data(url):
- df = pd.read_csv(url)
- return df
-
-df = load_data("https://github.com/plotly/datasets/raw/master/uber-rides-data1.csv")
-st.dataframe(df)
-
-st.button("Rerun")
-```
-
-Run the app again. You'll notice that the slow download only happens on the first run. Every subsequent rerun should be almost instant! 💨
-
-#### Behavior
-
-
-
-How does this work? Let's go through the behavior of `st.cache_data` step by step:
-
-- On the first run, Streamlit recognizes that it has never called the `load_data` function with the specified parameter value (the URL of the CSV file) So it runs the function and downloads the data.
-- Now our caching mechanism becomes active: the returned DataFrame is serialized (converted to bytes) via [pickle](https://docs.python.org/3/library/pickle.html) and stored in the cache (together with the value of the `url` parameter).
-- On the next run, Streamlit checks the cache for an entry of `load_data` with the specific `url`. There is one! So it retrieves the cached object, deserializes it to a DataFrame, and returns it instead of re-running the function and downloading the data again.
-
-This process of serializing and deserializing the cached object creates a copy of our original DataFrame. While this copying behavior may seem unnecessary, it's what we want when caching data objects since it effectively prevents mutation and concurrency issues. Read the section “[Mutation and concurrency issues](#mutation-and-concurrency-issues)" below to understand this in more detail.
-
-#### Examples
-
-
-
-**DataFrame transformations**
-
-In the example above, we already showed how to cache loading a DataFrame. It can also be useful to cache DataFrame transformations such as `df.filter`, `df.apply`, or `df.sort_values`. Especially with large DataFrames, these operations can be slow.
-
-```python
-@st.cache_data
-def transform(df):
- df = df.filter(items=['one', 'three'])
- df = df.apply(np.sum, axis=0)
- return df
-```
-
-**Array computations**
-
-Similarly, it can make sense to cache computations on NumPy arrays:
-
-```python
-@st.cache_data
-def add(arr1, arr2):
- return arr1 + arr2
-```
-
-**Database queries**
-
-You usually make SQL queries to load data into your app when working with databases. Repeatedly running these queries can be slow, cost money, and degrade the performance of your database. We strongly recommend caching any database queries in your app. See also [our guides on connecting Streamlit to different databases](/knowledge-base/tutorials/databases) for in-depth examples.
-
-```python
-connection = database.connect()
-
-@st.cache_data
-def query():
- return pd.read_sql_query("SELECT * from table", connection)
-```
-
-
-
-You should set a `ttl` (time to live) to get new results from your database. If you set `st.cache_data(ttl=3600)`, Streamlit invalidates any cached values after 1 hour (3600 seconds) and runs the cached function again. See details in [Controlling cache size and duration](#controlling-cache-size-and-duration).
-
-
-**API calls**
-
-Similarly, it makes sense to cache API calls. Doing so also avoids rate limits.
-
-```python
-@st.cache_data
-def api_call():
- response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
- return response.json()
-```
-
-**Running ML models (inference)**
-
-Running complex machine learning models can use significant time and memory. To avoid rerunning the same computations over and over, use caching.
-
-```python
-@st.cache_data
-def run_model(inputs):
- return model(inputs)
-```
-
-### st.cache_resource
-
-`st.cache_resource` is the right command to cache “resources" that should be available globally across all users, sessions, and reruns. It has more limited use cases than `st.cache_data`, especially for caching database connections and ML models.
-
-#### Usage
-
-As an example for `st.cache_resource`, let's look at a typical machine learning app. As a first step, we need to load an ML model. We do this with [Hugging Face's transformers library](https://huggingface.co/docs/transformers/index):
-
-```python
-from transformers import pipeline
-model = pipeline("sentiment-analysis") # 👈 Load the model
-```
-
-If we put this code into a Streamlit app directly, the app will load the model at each rerun or user interaction. Repeatedly loading the model poses two problems:
-
-- Loading the model takes time and slows down the app.
-- Each session loads the model from scratch, which takes up a huge amount of memory.
-
-Instead, it would make much more sense to load the model once and use that same object across all users and sessions. That's exactly the use case for `st.cache_resource`! Let's add it to our app and process some text the user entered:
-
-```python
-from transformers import pipeline
-
-@st.cache_resource # 👈 Add the caching decorator
-def load_model():
- return pipeline("sentiment-analysis")
-
-model = load_model()
-
-query = st.text_input("Your query", value="I love Streamlit! 🎈")
-if query:
- result = model(query)[0] # 👈 Classify the query text
- st.write(result)
-```
-
-If you run this app, you'll see that the app calls `load_model` only once – right when the app starts. Subsequent runs will reuse that same model stored in the cache, saving time and memory!
-
-#### Behavior
-
-
-
-Using `st.cache_resource` is very similar to using `st.cache_data`. But there are a few important differences in behavior:
-
-- `st.cache_resource` does **not** create a copy of the cached return value but instead stores the object itself in the cache. All mutations on the function's return value directly affect the object in the cache, so you must ensure that mutations from multiple sessions do not cause problems. In short, the return value must be thread-safe.
-
-
-
- Using `st.cache_resource` on objects that are not thread-safe might lead to crashes or corrupted data. Learn more below under [Mutation and concurrency issues](#mutation-and-concurrency-issues).
-
-
-- Not creating a copy means there's just one global instance of the cached return object, which saves memory, e.g. when using a large ML model. In computer science terms, we create a [singleton](https://en.wikipedia.org/wiki/Singleton_pattern).
-- Return values of functions do not need to be serializable. This behavior is great for types not serializable by nature, e.g., database connections, file handles, or threads. Caching these objects with `st.cache_data` is not possible.
-
-#### Examples
-
-
-
-**Database connections**
-
-`st.cache_resource` is useful for connecting to databases. Usually, you're creating a connection object that you want to reuse globally for every query. Creating a new connection object at each run would be inefficient and might lead to connection errors. That's exactly what `st.cache_resource` can do, e.g., for a Postgres database:
-
-```python
-@st.cache_resource
-def init_connection():
- host = "hh-pgsql-public.ebi.ac.uk"
- database = "pfmegrnargs"
- user = "reader"
- password = "NWDMCE5xdipIjRrp"
- return psycopg2.connect(host=host, database=database, user=user, password=password)
-
-conn = init_connection()
-```
-
-Of course, you can do the same for any other database. Have a look at [our guides on how to connect Streamlit to databases](/knowledge-base/tutorials/databases) for in-depth examples.
-
-**Loading ML models**
-
-Your app should always cache ML models, so they are not loaded into memory again for every new session. See the [example](#usage-1) above for how this works with 🤗 Hugging Face models. You can do the same thing for PyTorch, TensorFlow, etc. Here's an example for PyTorch:
-
-```python
-@st.cache_resource
-def load_model():
- model = torchvision.models.resnet50(weights=ResNet50_Weights.DEFAULT)
- model.eval()
- return model
-
-model = load_model()
-```
-
-### Deciding which caching decorator to use
-
-
-
-The sections above showed many common examples for each caching decorator. But there are edge cases for which it's less trivial to decide which caching decorator to use. Eventually, it all comes down to the difference between “data" and “resource":
-
-- Data are serializable objects (objects that can be converted to bytes via [pickle](https://docs.python.org/3/library/pickle.html)) that you could easily save to disk. Imagine all the types you would usually store in a database or on a file system – basic types like str, int, and float, but also arrays, DataFrames, images, or combinations of these types (lists, tuples, dicts, and so on).
-- Resources are unserializable objects that you usually would not save to disk or a database. They are often more complex, non-permanent objects like database connections, ML models, file handles, threads, etc.
-
-From the types listed above, it should be obvious that most objects in Python are “data." That's also why `st.cache_data` is the correct command for almost all use cases. `st.cache_resource` is a more exotic command that you should only use in specific situations.
-
-Or if you're lazy and don't want to think too much, look up your use case or return type in the table below 😉:
-
-| Use case | Typical return types | Caching decorator |
-| :----------------------------------- | -------------------------------------------------------------------------------------------------------------------------: | -----------------------------------------------------------------------------------------------------------------------------------------------------------: |
-| Reading a CSV file with pd.read_csv | pandas.DataFrame | st.cache_data |
-| Reading a text file | str, list of str | st.cache_data |
-| Transforming pandas dataframes | pandas.DataFrame, pandas.Series | st.cache_data |
-| Computing with numpy arrays | numpy.ndarray | st.cache_data |
-| Simple computations with basic types | str, int, float, … | st.cache_data |
-| Querying a database | pandas.DataFrame | st.cache_data |
-| Querying an API | pandas.DataFrame, str, dict | st.cache_data |
-| Running an ML model (inference) | pandas.DataFrame, str, int, dict, list | st.cache_data |
-| Creating or processing images | PIL.Image.Image, numpy.ndarray | st.cache_data |
-| Creating charts | matplotlib.figure.Figure, plotly.graph_objects.Figure, altair.Chart | st.cache_data (but some libraries require st.cache_resource, since the chart object is not serializable – make sure not to mutate the chart after creation!) |
-| Loading ML models | transformers.Pipeline, torch.nn.Module, tensorflow.keras.Model | st.cache_resource |
-| Initializing database connections | pyodbc.Connection, sqlalchemy.engine.base.Engine, psycopg2.connection, mysql.connector.MySQLConnection, sqlite3.Connection | st.cache_resource |
-| Opening persistent file handles | \_io.TextIOWrapper | st.cache_resource |
-| Opening persistent threads | threading.thread | st.cache_resource |
-
-## Advanced usage
-
-### Controlling cache size and duration
-
-If your app runs for a long time and constantly caches functions, you might run into two problems:
-
-1. The app runs out of memory because the cache is too large.
-2. Objects in the cache become stale, e.g. because you cached old data from a database.
-
-You can combat these problems with the `ttl` and `max_entries` parameters, which are available for both caching decorators.
-
-**The `ttl` (time-to-live) parameter**
-
-`ttl` sets a time to live on a cached function. If that time is up and you call the function again, the app will discard any old, cached values, and the function will be rerun. The newly computed value will then be stored in the cache. This behavior is useful for preventing stale data (problem 2) and the cache from growing too large (problem 1). Especially when pulling data from a database or API, you should always set a `ttl` so you are not using old data. Here's an example:
-
-```python
-@st.cache_data(ttl=3600) # 👈 Cache data for 1 hour (=3600 seconds)
-def get_api_data():
- data = api.get(...)
- return data
-```
-
-
-
-You can also set `ttl` values using `timedelta`, e.g., `ttl=datetime.timedelta(hours=1)`.
-
-
-**The `max_entries` parameter**
-
-`max_entries` sets the maximum number of entries in the cache. An upper bound on the number of cache entries is useful for limiting memory (problem 1), especially when caching large objects. The oldest entry will be removed when a new entry is added to a full cache. Here's an example:
-
-```python
-@st.cache_data(max_entries=1000) # 👈 Maximum 1000 entries in the cache
-def get_large_array(seed):
- np.random.seed(seed)
- arr = np.random.rand(100000)
- return arr
-```
-
-### Customizing the spinner
-
-By default, Streamlit shows a small loading spinner in the app when a cached function is running. You can modify it easily with the `show_spinner` parameter, which is available for both caching decorators:
-
-```python
-@st.cache_data(show_spinner=False) # 👈 Disable the spinner
-def get_api_data():
- data = api.get(...)
- return data
-
-@st.cache_data(show_spinner="Fetching data from API...") # 👈 Use custom text for spinner
-def get_api_data():
- data = api.get(...)
- return data
-```
-
-### Excluding input parameters
-
-In a cached function, all input parameters must be hashable. Let's quickly explain why and what it means. When the function is called, Streamlit looks at its parameter values to determine if it was cached before. Therefore, it needs a reliable way to compare the parameter values across function calls. Trivial for a string or int – but complex for arbitrary objects! Streamlit uses [hashing](https://en.wikipedia.org/wiki/Hash_function) to solve that. It converts the parameter to a stable key and stores that key. At the next function call, it hashes the parameter again and compares it with the stored hash key.
-
-Unfortunately, not all parameters are hashable! E.g., you might pass an unhashable database connection or ML model to your cached function. In this case, you can exclude input parameters from caching. Simply prepend the parameter name with an underscore (e.g., `_param1`), and it will not be used for caching. Even if it changes, Streamlit will return a cached result if all the other parameters match up.
-
-Here's an example:
-
-```python
-@st.cache_data
-def fetch_data(_db_connection, num_rows): # 👈 Don't hash _db_connection
- data = _db_connection.fetch(num_rows)
- return data
-
-connection = init_connection()
-fetch_data(connection, 10)
-```
-
-But what if you want to cache a function that takes an unhashable parameter? For example, you might want to cache a function that takes an ML model as input and returns the layer names of that model. Since the model is the only input parameter, you cannot exclude it from caching. In this case you can use the `hash_funcs` parameter to specify a custom hashing function for the model.
-
-### The `hash_funcs` parameter
-
-As described above, Streamlit's caching decorators hash the input parameters and cached function's signature to determine whether the function has been run before and has a return value stored ("cache hit") or needs to be run ("cache miss"). Input parameters that are not hashable by Streamlit's hashing implementation can be ignored by prepending an underscore to their name. But there two rare cases where this is undesirable. i.e. where you want to hash the parameter that Streamlit is unable to hash:
-
-1. When Streamlit's hashing mechanism fails to hash a parameter, resulting in a `UnhashableParamError` being raised.
-2. When you want to override Streamlit's default hashing mechanism for a parameter.
-
-Let's discuss each of these cases in turn with examples.
-
-#### Example 1: Hashing a custom class
-
-Streamlit does not know how to hash custom classes. If you pass a custom class to a cached function, Streamlit will raise a `UnhashableParamError`. For example, let's define a custom class `MyCustomClass` that accepts an initial integer score. Let's also define a cached function `multiply_score` that multiplies the score by a multiplier:
-
-```python
-import streamlit as st
-
-class MyCustomClass:
- def __init__(self, initial_score: int):
- self.my_score = initial_score
-
-@st.cache_data
-def multiply_score(obj: MyCustomClass, multiplier: int) -> int:
- return obj.my_score * multiplier
-
-initial_score = st.number_input("Enter initial score", value=15)
-
-score = MyCustomClass(initial_score)
-multiplier = 2
-
-st.write(multiply_score(score, multiplier))
-```
-
-If you run this app, you'll see that Streamlit raises a `UnhashableParamError` since it does not know how to hash `MyCustomClass`:
-
-```python
-UnhashableParamError: Cannot hash argument 'obj' (of type __main__.MyCustomClass) in 'multiply_score'.
-```
-
-To fix this, we can use the `hash_funcs` parameter to tell Streamlit how to hash `MyCustomClass`. We do this by passing a dictionary to `hash_funcs` that maps the name of the parameter to a hash function. The choice of hash function is up to the developer. In this case, let's define a custom hash function `hash_func` that takes the custom class as input and returns the score. We want the score to be the unique identifier of the object, so we can use it to deterministically hash the object:
-
-```python
-import streamlit as st
-
-class MyCustomClass:
- def __init__(self, initial_score: int):
- self.my_score = initial_score
-
-def hash_func(obj: MyCustomClass) -> int:
- return obj.my_score # or any other value that uniquely identifies the object
-
-@st.cache_data(hash_funcs={MyCustomClass: hash_func})
-def multiply_score(obj: MyCustomClass, multiplier: int) -> int:
- return obj.my_score * multiplier
-
-initial_score = st.number_input("Enter initial score", value=15)
-
-score = MyCustomClass(initial_score)
-multiplier = 2
-
-st.write(multiply_score(score, multiplier))
-```
-
-Now if you run the app, you'll see that Streamlit no longer raises a `UnhashableParamError` and the app runs as expected.
-
-Let's now consider the case where `multiply_score` is an attribute of `MyCustomClass` and we want to hash the entire object:
-
-```python
-import streamlit as st
-
-class MyCustomClass:
- def __init__(self, initial_score: int):
- self.my_score = initial_score
-
- @st.cache_data
- def multiply_score(self, multiplier: int) -> int:
- return self.my_score * multiplier
-
-initial_score = st.number_input("Enter initial score", value=15)
-
-score = MyCustomClass(initial_score)
-multiplier = 2
-
-st.write(score.multiply_score(multiplier))
-```
-
-If you run this app, you'll see that Streamlit raises a `UnhashableParamError` since it cannot hash the argument `'self' (of type __main__.MyCustomClass) in 'multiply_score'`. A simple fix here could be to use Python's `hash()` function to hash the object:
-
-```python
-import streamlit as st
-
-class MyCustomClass:
- def __init__(self, initial_score: int):
- self.my_score = initial_score
-
- @st.cache_data(hash_funcs={"__main__.MyCustomClass": lambda x: hash(x.my_score)})
- def multiply_score(self, multiplier: int) -> int:
- return self.my_score * multiplier
-
-initial_score = st.number_input("Enter initial score", value=15)
-
-score = MyCustomClass(initial_score)
-multiplier = 2
-
-st.write(score.multiply_score(multiplier))
-```
-
-Above, the hash function is defined as `lambda x: hash(x.my_score)`. This creates a hash based on the `my_score` attribute of the `MyCustomClass` instance. As long as `my_score` remains the same, the hash remains the same. Thus, the result of `multiply_score` can be retrieved from the cache without recomputation.
-
-As an astute Pythonista, you may have been tempted to use Python's `id()` function to hash the object like so:
-
-```python
-import streamlit as st
-
-class MyCustomClass:
- def __init__(self, initial_score: int):
- self.my_score = initial_score
-
- @st.cache_data(hash_funcs={"__main__.MyCustomClass": id})
- def multiply_score(self, multiplier: int) -> int:
- return self.my_score * multiplier
-
-initial_score = st.number_input("Enter initial score", value=15)
-
-score = MyCustomClass(initial_score)
-multiplier = 2
-
-st.write(score.multiply_score(multiplier))
-```
-
-If you run the app, you'll notice that Streamlit recomputes `multiply_score` each time even if `my_score` hasn't changed! Puzzled? In Python, `id()` returns the identity of an object, which is unique and constant for the object during its lifetime. This means that even if the `my_score` value is the same between two instances of `MyCustomClass`, `id()` will return different values for these two instances, leading to different hash values. As a result, Streamlit considers these two different instances as needing separate cached values, thus it recomputes the `multiply_score` each time even if `my_score` hasn't changed.
-
-This is why we discourage using it as hash func, and instead encourage functions that return deterministic, true hash values. That said, if you know what you're doing, you can use `id()` as a hash function. Just be aware of the consequences. For example, `id` is often the _correct_ hash func when you're passing the result of an `@st.cache_resource` function as the input param to another cached function. There's a whole class of object types that aren’t otherwise hashable.
-
-#### Example 2: Hashing a Pydantic model
-
-Let's consider another example where we want to hash a Pydantic model:
-
-```python
-import streamlit as st
-from pydantic import BaseModel
-
-class Person(BaseModel):
- name: str
-
-@st.cache_data
-def identity(person: Person):
- return person
-
-person = identity(Person(name="Lee"))
-st.write(f"The person is {person.name}")
-```
-
-Above, we define a custom class `Person` using Pydantic's `BaseModel` with a single attribute name. We also define an `identity` function which accepts an instance of `Person` as an arg and returns it without modification. This function is intended to cache the result, therefore, if called multiple times with the same `Person` instance, it won't recompute but return the cached instance.
-
-If you run the app, however, you'll run into a `UnhashableParamError: Cannot hash argument 'person' (of type __main__.Person) in 'identity'.` error. This is because Streamlit does not know how to hash the `Person` class. To fix this, we can use the `hash_funcs` kwarg to tell Streamlit how to hash `Person`.
-
-In the version below, we define a custom hash function `hash_func` that takes the `Person` instance as input and returns the name attribute. We want the name to be the unique identifier of the object, so we can use it to deterministically hash the object:
-
-```python
-import streamlit as st
-from pydantic import BaseModel
-
-class Person(BaseModel):
- name: str
-
-@st.cache_data(hash_funcs={Person: lambda p: p.name})
-def identity(person: Person):
- return person
-
-person = identity(Person(name="Lee"))
-st.write(f"The person is {person.name}")
-```
-
-#### Example 3: Hashing a ML model
-
-There may be cases where you want to pass your favorite machine learning model to a cached function. For example, let's say you want to pass a TensorFlow model to a cached function, based on what model the user selects in the app. You might try something like this:
-
-```python
-import streamlit as st
-import tensorflow as tf
-
-@st.cache_resource
-def load_base_model(option):
- if option == 1:
- return tf.keras.applications.ResNet50(include_top=False, weights="imagenet")
- else:
- return tf.keras.applications.MobileNetV2(include_top=False, weights="imagenet")
-
-@st.cache_resource
-def load_layers(base_model):
- return [layer.name for layer in base_model.layers]
-
-option = st.radio("Model 1 or 2", [1, 2])
-
-base_model = load_base_model(option)
-
-layers = load_layers(base_model)
-
-st.write(layers)
-```
-
-In the above app, the user can select one of two models. Based on the selection, the app loads the corresponding model and passes it to `load_layers`. This function then returns the names of the layers in the model. If you run the app, you'll see that Streamlit raises a `UnhashableParamError` since it cannot hash the argument `'base_model' (of type keras.engine.functional.Functional) in 'load_layers'`.
-
-If you disable hashing for `base_model` by prepending an underscore to its name, you'll observe that regardless of which base model is chosen, the layers displayed are same. This subtle bug is due to the fact that the `load_layers` function is not re-run when the base model changes. This is because Streamlit does not hash the `base_model` argument, so it does not know that the function needs to be re-run when the base model changes.
-
-To fix this, we can use the `hash_funcs` kwarg to tell Streamlit how to hash the `base_model` argument. In the version below, we define a custom hash function `hash_func`: `Functional: lambda x: x.name`. Our choice of hash func is informed by our knowledge that the `name` attribute of a `Functional` object or model uniquely identifies it. As long as the `name` attribute remains the same, the hash remains the same. Thus, the result of `load_layers` can be retrieved from the cache without recomputation.
-
-```python
-import streamlit as st
-import tensorflow as tf
-from keras.engine.functional import Functional
-
-@st.cache_resource
-def load_base_model(option):
- if option == 1:
- return tf.keras.applications.ResNet50(include_top=False, weights="imagenet")
- else:
- return tf.keras.applications.MobileNetV2(include_top=False, weights="imagenet")
-
-@st.cache_resource(hash_funcs={Functional: lambda x: x.name})
-def load_layers(base_model):
- return [layer.name for layer in base_model.layers]
-
-option = st.radio("Model 1 or 2", [1, 2])
-
-base_model = load_base_model(option)
-
-layers = load_layers(base_model)
-
-st.write(layers)
-```
-
-In the above case, we could also have used `hash_funcs={Functional: id}` as the hash function. This is because `id` is often the _correct_ hash func when you're passing the result of an `@st.cache_resource` function as the input param to another cached function.
-
-#### Example 4: Overriding Streamlit's default hashing mechanism
-
-Let's consider another example where we want to override Streamlit's default hashing mechanism for a pytz-localized datetime object:
-
-```python
-from datetime import datetime
-import pytz
-import streamlit as st
-
-tz = pytz.timezone("Europe/Berlin")
-
-@st.cache_data
-def load_data(dt):
- return dt
-
-now = datetime.now()
-st.text(load_data(dt=now))
-
-now_tz = tz.localize(datetime.now())
-st.text(load_data(dt=now_tz))
-```
-
-It may be surprising to see that although `now` and `now_tz` are of the same `` type, Streamlit does not how to hash `now_tz` and raises a `UnhashableParamError`. In this case, we can override Streamlit's default hashing mechanism for `datetime` objects by passing a custom hash function to the `hash_funcs` kwarg:
-
-```python
-from datetime import datetime
-
-import pytz
-import streamlit as st
-
-tz = pytz.timezone("Europe/Berlin")
-
-@st.cache_data(hash_funcs={datetime: lambda x: x.strftime("%a %d %b %Y, %I:%M%p")})
-def load_data(dt):
- return dt
-
-now = datetime.now()
-st.text(load_data(dt=now))
-
-now_tz = tz.localize(datetime.now())
-st.text(load_data(dt=now_tz))
-```
-
-Let's now consider a case where we want to override Streamlit's default hashing mechanism for NumPy arrays. While Streamlit natively hashes Pandas and NumPy objects, there may be cases where you want to override Streamlit's default hashing mechanism for these objects.
-
-For example, let's say we create a cache-decorated `show_data` function that accepts a NumPy array and returns it without modification. In the bellow app, `data = df["str"].unique()` (which is a NumPy array) is passed to the `show_data` function.
-
-```python
-import time
-import numpy as np
-import pandas as pd
-import streamlit as st
-
-@st.cache_data
-def get_data():
- df = pd.DataFrame({"num": [112, 112, 2, 3], "str": ["be", "a", "be", "c"]})
- return df
-
-@st.cache_data
-def show_data(data):
- time.sleep(2) # This makes the function take 2s to run
- return data
-
-df = get_data()
-data = df["str"].unique()
-
-st.dataframe(show_data(data))
-st.button("Re-run")
-```
-
-Since `data` is always the same, we expect the `show_data` function to return the cached value. However, if you run the app, and click the `Re-run` button, you'll notice that the `show_data` function is re-run each time. We can assume this behavior is a consequence of Streamlit's default hashing mechanism for NumPy arrays.
-
-To work around this, let's define a custom hash function `hash_func` that takes a NumPy array as input and returns a string representation of the array:
-
-```python
-import time
-import numpy as np
-import pandas as pd
-import streamlit as st
-
-@st.cache_data
-def get_data():
- df = pd.DataFrame({"num": [112, 112, 2, 3], "str": ["be", "a", "be", "c"]})
- return df
-
-@st.cache_data(hash_funcs={np.ndarray: str})
-def show_data(data):
- time.sleep(2) # This makes the function take 2s to run
- return data
-
-df = get_data()
-data = df["str"].unique()
-
-st.dataframe(show_data(data))
-st.button("Re-run")
-```
-
-Now if you run the app, and click the `Re-run` button, you'll notice that the `show_data` function is no longer re-run each time. It's important to note here that our choice of hash function was very naive and not necessarily the best choice. For example, if the NumPy array is large, converting it to a string representation may be expensive. In such cases, it is up to you as the developer to define what a good hash function is for your use case.
-
-#### Static elements
-
-Since version 1.16.0, cached functions can contain Streamlit commands! For example, you can do this:
-
-```python
-@st.cache_data
-def get_api_data():
- data = api.get(...)
- st.success("Fetched data from API!") # 👈 Show a success message
- return data
-```
-
-As we know, Streamlit only runs this function if it hasn't been cached before. On this first run, the `st.success` message will appear in the app. But what happens on subsequent runs? It still shows up! Streamlit realizes that there is an `st.` command inside the cached function, saves it during the first run, and replays it on subsequent runs. Replaying static elements works for both caching decorators.
-
-You can also use this functionality to cache entire parts of your UI:
-
-```python
-@st.cache_data
-def show_data():
- st.header("Data analysis")
- data = api.get(...)
- st.success("Fetched data from API!")
- st.write("Here is a plot of the data:")
- st.line_chart(data)
- st.write("And here is the raw data:")
- st.dataframe(data)
-```
-
-#### Input widgets
-
-You can also use [interactive input widgets](/library/api-reference/widgets) like `st.slider` or `st.text_input` in cached functions. Widget replay is an experimental feature at the moment. To enable it, you need to set the `experimental_allow_widgets` parameter:
-
-```python
-@st.cache_data(experimental_allow_widgets=True) # 👈 Set the parameter
-def get_data():
- num_rows = st.slider("Number of rows to get") # 👈 Add a slider
- data = api.get(..., num_rows)
- return data
-```
-
-Streamlit treats the slider like an additional input parameter to the cached function. If you change the slider position, Streamlit will see if it has already cached the function for this slider value. If yes, it will return the cached value. If not, it will rerun the function using the new slider value.
-
-Using widgets in cached functions is extremely powerful because it lets you cache entire parts of your app. But it can be dangerous! Since Streamlit treats the widget value as an additional input parameter, it can easily lead to excessive memory usage. Imagine your cached function has five sliders and returns a 100 MB DataFrame. Then we'll add 100 MB to the cache for _every permutation_ of these five slider values – even if the sliders do not influence the returned data! These additions can make your cache explode very quickly. Please be aware of this limitation if you use widgets in cached functions. We recommend using this feature only for isolated parts of your UI where the widgets directly influence the cached return value.
-
-
-
-Support for widgets in cached functions is experimental. We may change or remove it anytime without warning. Please use it with care!
-
-
-
-
-Two widgets are currently not supported in cached functions: `st.file_uploader` and `st.camera_input`. We may support them in the future. Feel free to [open a GitHub issue](https://github.com/streamlit/streamlit/issues) if you need them!
-
-
-### Dealing with large data
-
-As we explained, you should cache data objects with `st.cache_data`. But this can be slow for extremely large data, e.g., DataFrames or arrays with >100 million rows. That's because of the [copying behavior](#copying-behavior) of `st.cache_data`: on the first run, it serializes the return value to bytes and deserializes it on subsequent runs. Both operations take time.
-
-If you're dealing with extremely large data, it can make sense to use `st.cache_resource` instead. It does not create a copy of the return value via serialization/deserialization and is almost instant. But watch out: any mutation to the function's return value (such as dropping a column from a DataFrame or setting a value in an array) directly manipulates the object in the cache. You must ensure this doesn't corrupt your data or lead to crashes. See the section on [Mutation and concurrency issues](#mutation-and-concurrency-issues) below.
-
-When benchmarking `st.cache_data` on pandas DataFrames with four columns, we found that it becomes slow when going beyond 100 million rows. The table shows runtimes for both caching decorators at different numbers of rows (all with four columns):
-
-| | | 10M rows | 50M rows | 100M rows | 200M rows |
-| ----------------- | --------------- | :------: | :------: | :-------: | :-------: |
-| st.cache_data | First run\* | 0.4 s | 3 s | 14 s | 28 s |
-| | Subsequent runs | 0.2 s | 1 s | 2 s | 7 s |
-| st.cache_resource | First run\* | 0.01 s | 0.1 s | 0.2 s | 1 s |
-| | Subsequent runs | 0 s | 0 s | 0 s | 0 s |
-
-| |
-| :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| _\*For the first run, the table only shows the overhead time of using the caching decorator. It does not include the runtime of the cached function itself._ |
-
-### Mutation and concurrency issues
-
-In the sections above, we talked a lot about issues when mutating return objects of cached functions. This topic is complicated! But it's central to understanding the behavior differences between `st.cache_data` and `st.cache_resource`. So let's dive in a bit deeper.
-
-First, we should clearly define what we mean by mutations and concurrency:
-
-- By **mutations**, we mean any changes made to a cached function's return value _after_ that function has been called. I.e. something like this:
-
- ```python
- @st.cache_data
- def create_list():
- l = [1, 2, 3]
-
- l = create_list() # 👈 Call the function
- l[0] = 2 # 👈 Mutate its return value
- ```
-
-- By **concurrency**, we mean that multiple sessions can cause these mutations at the same time. Streamlit is a web framework that needs to handle many users and sessions connecting to an app. If two people view an app at the same time, they will both cause the Python script to rerun, which may manipulate cached return objects at the same time – concurrently.
-
-Mutating cached return objects can be dangerous. It can lead to exceptions in your app and even corrupt your data (which can be worse than a crashed app!). Below, we'll first explain the copying behavior of `st.cache_data` and show how it can avoid mutation issues. Then, we'll show how concurrent mutations can lead to data corruption and how to prevent it.
-
-#### Copying behavior
-
-`st.cache_data` creates a copy of the cached return value each time the function is called. This avoids most mutations and concurrency issues. To understand it in detail, let's go back to the [Uber ridesharing example](#usage) from the section on `st.cache_data` above. We are making two modifications to it:
-
-1. We are using `st.cache_resource` instead of `st.cache_data`. `st.cache_resource` does **not** create a copy of the cached object, so we can see what happens without the copying behavior.
-2. After loading the data, we manipulate the returned DataFrame (in place!) by dropping the column `"Lat"`.
-
-Here's the code:
-
-```python
-@st.cache_resource # 👈 Turn off copying behavior
-def load_data(url):
- df = pd.read_csv(url)
- return df
-
-df = load_data("https://raw.githubusercontent.com/plotly/datasets/master/uber-rides-data1.csv")
-st.dataframe(df)
-
-df.drop(columns=['Lat'], inplace=True) # 👈 Mutate the dataframe inplace
-
-st.button("Rerun")
-```
-
-Let's run it and see what happens! The first run should work fine. But in the second run, you see an exception: `KeyError: "['Lat'] not found in axis"`. Why is that happening? Let's go step by step:
-
-- On the first run, Streamlit runs `load_data` and stores the resulting DataFrame in the cache. Since we're using `st.cache_resource`, it does **not** create a copy but stores the original DataFrame.
-- Then we drop the column `"Lat"` from the DataFrame. Note that this is dropping the column from the _original_ DataFrame stored in the cache. We are manipulating it!
-- On the second run, Streamlit returns that exact same manipulated DataFrame from the cache. It does not have the column `"Lat"` anymore! So our call to `df.drop` results in an exception. Pandas cannot drop a column that doesn't exist.
-
-The copying behavior of `st.cache_data` prevents this kind of mutation error. Mutations can only affect a specific copy and not the underlying object in the cache. The next rerun will get its own, unmutated copy of the DataFrame. You can try it yourself, just replace `st.cache_resource` with `st.cache_data` above, and you'll see that everything works.
-
-Because of this copying behavior, `st.cache_data` is the recommended way to cache data transforms and computations – anything that returns a serializable object.
-
-#### Concurrency issues
-
-Now let's look at what can happen when multiple users concurrently mutate an object in the cache. Let's say you have a function that returns a list. Again, we are using `st.cache_resource` to cache it so that we are not creating a copy:
-
-```python
-@st.cache_resource
-def create_list():
- l = [1, 2, 3]
- return l
-
-l = create_list()
-first_list_value = l[0]
-l[0] = first_list_value + 1
-
-st.write("l[0] is:", l[0])
-```
-
-Let's say user A runs the app. They will see the following output:
-
-```python
-l[0] is: 2
-```
-
-Let's say another user, B, visits the app right after. In contrast to user A, they will see the following output:
-
-```python
-l[0] is: 3
-```
-
-Now, user A reruns the app immediately after user B. They will see the following output:
-
-```python
-l[0] is: 4
-```
-
-What is happening here? Why are all outputs different?
-
-- When user A visits the app, `create_list()` is called, and the list `[1, 2, 3]` is stored in the cache. This list is then returned to user A. The first value of the list, `1`, is assigned to `first_list_value` , and `l[0]` is changed to `2`.
-- When user B visits the app, `create_list()` returns the mutated list from the cache: `[2, 2, 3]`. The first value of the list, `2`, is assigned to `first_list_value` and `l[0]` is changed to `3`.
-- When user A reruns the app, `create_list()` returns the mutated list again: `[3, 2, 3]`. The first value of the list, `3`, is assigned to `first_list_value,` and `l[0]` is changed to 4.
-
-If you think about it, this makes sense. Users A and B use the same list object (the one stored in the cache). And since the list object is mutated, user A's change to the list object is also reflected in user B's app.
-
-This is why you must be careful about mutating objects cached with `st.cache_resource`, especially when multiple users access the app concurrently. If we had used `st.cache_data` instead of `st.cache_resource`, the app would have copied the list object for each user, and the above example would have worked as expected – users A and B would have both seen:
-
-```python
-l[0] is: 2
-```
-
-
-
-This toy example might seem benign. But data corruption can be extremely dangerous! Imagine we had worked with the financial records of a large bank here. You surely don't want to wake up with less money on your account just because someone used the wrong caching decorator 😉
-
-
-
-## Migrating from st.cache
-
-We introduced the caching commands described above in Streamlit 1.18.0. Before that, we had one catch-all command `st.cache`. Using it was often confusing, resulted in weird exceptions, and was slow. That's why we replaced `st.cache` with the new commands in 1.18.0 (read more in this [blog post](https://blog.streamlit.io/introducing-two-new-caching-commands-to-replace-st-cache/)). The new commands provide a more intuitive and efficient way to cache your data and resources and are intended to replace `st.cache` in all new development.
-
-If your app is still using `st.cache`, don't despair! Here are a few notes on migrating:
-
-- `st.cache` is deprecated. • New versions of Streamlit will show a deprecation warning if your app uses it.
-- We will not remove `st.cache` soon, so you don't need to worry about your 2-year-old app breaking. But we encourage you to try the new commands going forward – they will be way less annoying!
-- Switching code to the new commands should be easy in most cases. To decide whether to use `st.cache_data` or `st.cache_resource`, read [Deciding which caching decorator to use](#deciding-which-caching-decorator-to-use). Streamlit will also recognize common use cases and show hints right in the deprecation warnings.
-- Most parameters from `st.cache` are also present in the new commands, with a few exceptions:
- - `allow_output_mutation` does not exist anymore. You can safely delete it. Just make sure you use the right caching command for your use case.
- - `suppress_st_warning` does not exist anymore. You can safely delete it. Cached functions can now contain Streamlit commands and will replay them. If you want to use widgets inside cached functions, set `experimental_allow_widgets=True`. See [here](#using-streamlit-commands-in-cached-functions).
- - `hash_funcs` does not exist anymore. You can exclude parameters from caching (and being hashed) by prepending them with an underscore: `_excluded_param`. See [here](#excluding-input-parameters).
-
-If you have any questions or issues during the migration process, please contact us on the [forum](https://discuss.streamlit.io/), and we will be happy to assist you. 🎈
diff --git a/data/library/advanced-features/cli.md b/data/library/advanced-features/cli.md
deleted file mode 100644
index 59b7030ee..000000000
--- a/data/library/advanced-features/cli.md
+++ /dev/null
@@ -1,68 +0,0 @@
----
-title: Command-line options
-slug: /library/advanced-features/cli
----
-
-# Command-line interface
-
-When you install Streamlit, a command-line (CLI) tool gets installed
-as well. The purpose of this tool is to run Streamlit apps, change Streamlit configuration options,
-and help you diagnose and fix issues.
-
-To see all of the supported commands:
-
-```bash
-streamlit --help
-```
-
-### Run Streamlit apps
-
-```bash
-streamlit run your_script.py [-- script args]
-```
-
-Runs your app. At any time you can stop the server with **Ctrl+c**.
-
-
-
-When passing your script some custom arguments, **they must be passed after
-two dashes**. Otherwise the arguments get interpreted as arguments to Streamlit
-itself.
-
-
-
-To see the Streamlit 'Hello, World!' example app, run `streamlit hello`.
-
-### View Streamlit version
-
-To see what version of Streamlit is installed, just type:
-
-```bash
-streamlit version
-```
-
-### View documentation
-
-```bash
-streamlit docs
-```
-
-Opens the Streamlit documentation (i.e. this website) in a web browser.
-
-### Clear cache
-
-```bash
-streamlit cache clear
-```
-
-Clears persisted files from the on-disk [Streamlit cache](/library/api-reference/performance), if
-present.
-
-### View all configuration options
-
-As described in [Configuration](/library/advanced-features/configuration), Streamlit has several
-configuration options. To view them all, including their current values, just type:
-
-```bash
-streamlit config show
-```
diff --git a/data/library/advanced-features/configuration.md b/data/library/advanced-features/configuration.md
deleted file mode 100644
index 793a2b502..000000000
--- a/data/library/advanced-features/configuration.md
+++ /dev/null
@@ -1,790 +0,0 @@
----
-title: Configuration
-slug: /library/advanced-features/configuration
----
-
-# Configuration
-
-Streamlit provides four different ways to set configuration options. This list is in reverse order of precedence, i.e. command line flags take precedence over environment variables when the same configuration option is provided multiple times.
-
-
-
-If changes to `.streamlit/config.toml` are made _while_ the app is running, the server needs to be restarted for changes to be reflected in the app.
-
-
-
-1. In a **global config file** at `~/.streamlit/config.toml` for macOS/Linux or `%userprofile%/.streamlit/config.toml` for Windows:
-
- ```toml
- [server]
- port = 80
- ```
-
-2. In a **per-project config file** at `$CWD/.streamlit/config.toml`, where
- `$CWD` is the folder you're running Streamlit from.
-
-3. Through `STREAMLIT_*` **environment variables**, such as:
-
- ```bash
- export STREAMLIT_SERVER_PORT=80
- export STREAMLIT_SERVER_COOKIE_SECRET=dontforgottochangeme
- ```
-
-4. As **flags on the command line** when running `streamlit run`:
-
- ```bash
- streamlit run your_script.py --server.port 80
- ```
-
-
-## Telemetry
-
-As mentioned during the installation process, Streamlit collects usage statistics. You can find out
-more by reading our [Privacy Notice](https://streamlit.io/privacy-policy), but the high-level
-summary is that although we collect telemetry data we cannot see and do not store information
-contained in Streamlit apps.
-
-If you'd like to opt out of usage statistics, add the following to your config file:
-
-```toml
-[browser]
-gatherUsageStats = false
-```
-
-## Theming
-
-You can change the base colors of your app using the `[theme]` section of the configuration system.
-To learn more, see [Theming.](/library/advanced-features/theming)
-
-## View all configuration options
-
-As described in [Command-line options](/library/advanced-features/cli), you can
-view all available configuration option using:
-
-```bash
-streamlit config show
-```
-
-Below are all the sections and options you can have in your `.streamlit/config.toml` file:
-
-### Global
-
-```toml
-[global]
-
-# By default, Streamlit checks if the Python watchdog module is available
-# and, if not, prints a warning asking for you to install it. The watchdog
-# module is not required, but highly recommended. It improves Streamlit's
-# ability to detect changes to files in your filesystem.
-
-# If you'd like to turn off this warning, set this to True.
-
-# Default: false
-disableWatchdogWarning = false
-
-# By default, Streamlit displays a warning when a user sets both a widget
-# default value in the function defining the widget and a widget value via
-# the widget's key in `st.session_state`.
-
-# If you'd like to turn off this warning, set this to True.
-
-# Default: false
-disableWidgetStateDuplicationWarning = false
-
-# If True, will show a warning when you run a Streamlit-enabled script
-# via "python my_script.py".
-
-# Default: true
-showWarningOnDirectExecution = true
-
-# DataFrame serialization.
-
-# Acceptable values:
-# - 'legacy' : Serialize DataFrames using Streamlit's custom format. Slow
-# but battle-tested.
-# - 'arrow' : Serialize DataFrames using Apache Arrow. Much faster and
-# versatile.
-
-# Default: "arrow"
-dataFrameSerialization = "arrow"
-```
-
-### Logger
-
-```toml
-[logger]
-
-# Level of logging: 'error', 'warning', 'info', or 'debug'.
-
-# Default: 'info'
-level = "info"
-
-# String format for logging messages. If logger.datetimeFormat is set,
-# logger messages will default to `%(asctime)s.%(msecs)03d %(message)s`. See
-# Python's documentation for available attributes:
-# https://docs.python.org/2.6/library/logging.html#formatter-objects
-
-# Default: "%(asctime)s %(message)s"
-messageFormat = "%(asctime)s %(message)s"
-```
-
-### Client
-
-```toml
-[client]
-
-# Whether to enable st.cache. This does not affect st.cache_data or
-# st.cache_resource.
-
-# Default: true
-caching = true
-
-# If false, makes your Streamlit script not draw to a
-# Streamlit app.
-
-# Default: true
-displayEnabled = true
-
-# Controls whether uncaught app exceptions and deprecation warnings
-# are displayed in the browser. By default, this is set to True and
-# Streamlit displays app exceptions and associated tracebacks, and
-# deprecation warnings, in the browser.
-
-# If set to False, deprecation warnings and full exception messages
-# will print to the console only. Exceptions will still display in the
-# browser with a generic error message. For now, the exception type and
-# traceback show in the browser also, but they will be removed in the
-# future.
-
-# Default: true
-showErrorDetails = true
-
-# Change the visibility of items in the toolbar, options menu,
-# and settings dialog (top right of the app).
-
-# Allowed values:
-# * "auto" : Show the developer options if the app is accessed through
-# localhost or through Streamlit Community Cloud as a developer.
-# Hide them otherwise.
-# * "developer" : Show the developer options.
-# * "viewer" : Hide the developer options.
-# * "minimal" : Show only options set externally (e.g. through
-# Streamlit Community Cloud) or through st.set_page_config.
-# If there are no options left, hide the menu.
-
-# Default: "auto"
-toolbarMode = "auto"
-```
-
-### Runner
-
-```toml
-[runner]
-
-# Allows you to type a variable or string by itself in a single line of
-# Python code to write it to the app.
-
-# Default: true
-magicEnabled = true
-
-# Install a Python tracer to allow you to stop or pause your script at
-# any point and introspect it. As a side-effect, this slows down your
-# script's execution.
-
-# Default: false
-installTracer = false
-
-# Sets the MPLBACKEND environment variable to Agg inside Streamlit to
-# prevent Python crashing.
-
-# Default: true
-fixMatplotlib = true
-
-# Run the Python Garbage Collector after each script execution. This
-# can help avoid excess memory use in Streamlit apps, but could
-# introduce delay in rerunning the app script for high-memory-use
-# applications.
-
-# Default: true
-postScriptGC = true
-
-# Handle script rerun requests immediately, rather than waiting for script
-# execution to reach a yield point. This makes Streamlit much more
-# responsive to user interaction, but it can lead to race conditions in
-# apps that mutate session_state data outside of explicit session_state
-# assignment statements.
-
-# Default: true
-fastReruns = true
-
-# Raise an exception after adding unserializable data to Session State.
-# Some execution environments may require serializing all data in Session
-# State, so it may be useful to detect incompatibility during development,
-# or when the execution environment will stop supporting it in the future.
-
-# Default: false
-enforceSerializableSessionState = false
-```
-
-### Server
-
-```toml
-[server]
-
-# List of folders that should not be watched for changes. This
-# impacts both "Run on Save" and @st.cache.
-
-# Relative paths will be taken as relative to the current working directory.
-
-# Example: ['/home/user1/env', 'relative/path/to/folder']
-
-# Default: []
-folderWatchBlacklist = []
-
-# Change the type of file watcher used by Streamlit, or turn it off
-# completely.
-
-# Allowed values:
-# * "auto" : Streamlit will attempt to use the watchdog module, and
-# falls back to polling if watchdog is not available.
-# * "watchdog" : Force Streamlit to use the watchdog module.
-# * "poll" : Force Streamlit to always use polling.
-# * "none" : Streamlit will not watch files.
-
-# Default: "auto"
-fileWatcherType = "auto"
-
-# Symmetric key used to produce signed cookies. If deploying on multiple
-# replicas, this should be set to the same value across all replicas to ensure
-# they all share the same secret.
-
-# Default: randomly generated secret key.
-cookieSecret = "a-random-key-appears-here"
-
-# If false, will attempt to open a browser window on start.
-
-# Default: false unless (1) we are on a Linux box where DISPLAY is unset, or
-# (2) we are running in the Streamlit Atom plugin.
-# headless = false
-
-# Automatically rerun script when the file is modified on disk.
-
-# Default: false
-runOnSave = false
-
-# The address where the server will listen for client and browser
-# connections. Use this if you want to bind the server to a specific address.
-# If set, the server will only be accessible from this address, and not from
-# any aliases (like localhost).
-
-# Default: (unset)
-# address =
-
-# The port where the server will listen for browser connections.
-
-# Default: 8501
-port = 8501
-
-# The base path for the URL where Streamlit should be served from.
-
-# Default: ""
-baseUrlPath = ""
-
-# Enables support for Cross-Origin Resource Sharing (CORS) protection, for
-# added security.
-
-# Due to conflicts between CORS and XSRF, if `server.enableXsrfProtection` is
-# on and `server.enableCORS` is off at the same time, we will prioritize
-# `server.enableXsrfProtection`.
-
-# Default: true
-enableCORS = true
-
-# Enables support for Cross-Site Request Forgery (XSRF) protection, for added
-# security.
-
-# Due to conflicts between CORS and XSRF, if `server.enableXsrfProtection` is
-# on and `server.enableCORS` is off at the same time, we will prioritize
-# `server.enableXsrfProtection`.
-
-# Default: true
-enableXsrfProtection = true
-
-# Max size, in megabytes, for files uploaded with the file_uploader.
-
-# Default: 200
-maxUploadSize = 200
-
-# Max size, in megabytes, of messages that can be sent via the WebSocket
-# connection.
-
-# Default: 200
-maxMessageSize = 200
-
-# Enables support for websocket compression.
-
-# Default: false
-enableWebsocketCompression = false
-
-# Enable serving files from a `static` directory in the running app's
-# directory.
-
-# Default: false
-enableStaticServing = false
-
-# Server certificate file for connecting via HTTPS.
-# Must be set at the same time as "server.sslKeyFile".
-
-# ['DO NOT USE THIS OPTION IN A PRODUCTION ENVIRONMENT. It has not gone through
-# security audits or performance tests. For the production environment, we
-# recommend performing SSL termination by the load balancer or the reverse
-# proxy.']
-# sslCertFile =
-
-# Cryptographic key file for connecting via HTTPS.
-# Must be set at the same time as "server.sslCertFile".
-
-# ['DO NOT USE THIS OPTION IN A PRODUCTION ENVIRONMENT. It has not gone through
-# security audits or performance tests. For the production environment, we
-# recommend performing SSL termination by the load balancer or the reverse
-# proxy.']
-# sslKeyFile =
-```
-
-### Browser
-
-```toml
-[browser]
-
-# Internet address where users should point their browsers in order to
-# connect to the app. Can be IP address or DNS name and path.
-
-# This is used to:
-# - Set the correct URL for CORS and XSRF protection purposes.
-# - Show the URL on the terminal
-# - Open the browser
-
-# Default: "localhost"
-serverAddress = "localhost"
-
-# Whether to send usage statistics to Streamlit.
-
-# Default: true
-gatherUsageStats = true
-
-# Port where users should point their browsers in order to connect to the
-# app.
-
-# This is used to:
-# - Set the correct URL for CORS and XSRF protection purposes.
-# - Show the URL on the terminal
-# - Open the browser
-
-# Default: whatever value is set in server.port.
-serverPort = 8501
-```
-
-### Mapbox
-
-```toml
-[mapbox]
-
-# Configure Streamlit to use a custom Mapbox
-# token for elements like st.pydeck_chart and st.map.
-# To get a token for yourself, create an account at
-# https://mapbox.com. It's free (for moderate usage levels)!
-
-# Default: ""
-token = ""
-```
-
-### Deprecation
-
-```toml
-[deprecation]
-
-# Set to false to disable the deprecation warning for the file uploader
-# encoding.
-
-# Default: true
-showfileUploaderEncoding = true
-
-# Set to false to disable the deprecation warning for using the global pyplot
-# instance.
-
-# Default: true
-showPyplotGlobalUse = true
-```
-
-### Theme
-
-```toml
-[theme]
-
-# The preset Streamlit theme that your custom theme inherits from.
-# One of "light" or "dark".
-# base =
-
-# Primary accent color for interactive elements.
-# primaryColor =
-
-# Background color for the main content area.
-# backgroundColor =
-
-# Background color used for the sidebar and most interactive widgets.
-# secondaryBackgroundColor =
-
-# Color used for almost all text.
-# textColor =
-
-# Font family for all text in the app, except code blocks. One of "sans serif",
-# "serif", or "monospace".
-# font =
-```
-
-
-
-This is the entire `config.toml` file with all the options for version 1.25.0:
-
-```toml
-[global]
-
-# By default, Streamlit checks if the Python watchdog module is available
-# and, if not, prints a warning asking for you to install it. The watchdog
-# module is not required, but highly recommended. It improves Streamlit's
-# ability to detect changes to files in your filesystem.
-
-# If you'd like to turn off this warning, set this to True.
-
-# Default: false
-disableWatchdogWarning = false
-
-# By default, Streamlit displays a warning when a user sets both a widget
-# default value in the function defining the widget and a widget value via
-# the widget's key in `st.session_state`.
-
-# If you'd like to turn off this warning, set this to True.
-
-# Default: false
-disableWidgetStateDuplicationWarning = false
-
-# If True, will show a warning when you run a Streamlit-enabled script
-# via "python my_script.py".
-
-# Default: true
-showWarningOnDirectExecution = true
-
-# DataFrame serialization.
-
-# Acceptable values:
-# - 'legacy' : Serialize DataFrames using Streamlit's custom format. Slow
-# but battle-tested.
-# - 'arrow' : Serialize DataFrames using Apache Arrow. Much faster and
-# versatile.
-
-# Default: "arrow"
-dataFrameSerialization = "arrow"
-
-[logger]
-
-# Level of logging: 'error', 'warning', 'info', or 'debug'.
-
-# Default: 'info'
-level = "info"
-
-# String format for logging messages. If logger.datetimeFormat is set,
-# logger messages will default to `%(asctime)s.%(msecs)03d %(message)s`. See
-# Python's documentation for available attributes:
-# https://docs.python.org/2.6/library/logging.html#formatter-objects
-
-# Default: "%(asctime)s %(message)s"
-messageFormat = "%(asctime)s %(message)s"
-
-[client]
-
-# Whether to enable st.cache. This does not affect st.cache_data or
-# st.cache_resource.
-
-# Default: true
-caching = true
-
-# If false, makes your Streamlit script not draw to a
-# Streamlit app.
-
-# Default: true
-displayEnabled = true
-
-# Controls whether uncaught app exceptions and deprecation warnings
-# are displayed in the browser. By default, this is set to True and
-# Streamlit displays app exceptions and associated tracebacks, and
-# deprecation warnings, in the browser.
-
-# If set to False, deprecation warnings and full exception messages
-# will print to the console only. Exceptions will still display in the
-# browser with a generic error message. For now, the exception type and
-# traceback show in the browser also, but they will be removed in the
-# future.
-
-# Default: true
-showErrorDetails = true
-
-# Change the visibility of items in the toolbar, options menu,
-# and settings dialog (top right of the app).
-
-# Allowed values:
-# * "auto" : Show the developer options if the app is accessed through
-# localhost or through Streamlit Community Cloud as a developer.
-# Hide them otherwise.
-# * "developer" : Show the developer options.
-# * "viewer" : Hide the developer options.
-# * "minimal" : Show only options set externally (e.g. through
-# Streamlit Community Cloud) or through st.set_page_config.
-# If there are no options left, hide the menu.
-
-# Default: "auto"
-toolbarMode = "auto"
-
-[runner]
-
-# Allows you to type a variable or string by itself in a single line of
-# Python code to write it to the app.
-
-# Default: true
-magicEnabled = true
-
-# Install a Python tracer to allow you to stop or pause your script at
-# any point and introspect it. As a side-effect, this slows down your
-# script's execution.
-
-# Default: false
-installTracer = false
-
-# Sets the MPLBACKEND environment variable to Agg inside Streamlit to
-# prevent Python crashing.
-
-# Default: true
-fixMatplotlib = true
-
-# Run the Python Garbage Collector after each script execution. This
-# can help avoid excess memory use in Streamlit apps, but could
-# introduce delay in rerunning the app script for high-memory-use
-# applications.
-
-# Default: true
-postScriptGC = true
-
-# Handle script rerun requests immediately, rather than waiting for script
-# execution to reach a yield point. This makes Streamlit much more
-# responsive to user interaction, but it can lead to race conditions in
-# apps that mutate session_state data outside of explicit session_state
-# assignment statements.
-
-# Default: true
-fastReruns = true
-
-# Raise an exception after adding unserializable data to Session State.
-# Some execution environments may require serializing all data in Session
-# State, so it may be useful to detect incompatibility during development,
-# or when the execution environment will stop supporting it in the future.
-
-# Default: false
-enforceSerializableSessionState = false
-
-[server]
-
-# List of folders that should not be watched for changes. This
-# impacts both "Run on Save" and @st.cache.
-
-# Relative paths will be taken as relative to the current working directory.
-
-# Example: ['/home/user1/env', 'relative/path/to/folder']
-
-# Default: []
-folderWatchBlacklist = []
-
-# Change the type of file watcher used by Streamlit, or turn it off
-# completely.
-
-# Allowed values:
-# * "auto" : Streamlit will attempt to use the watchdog module, and
-# falls back to polling if watchdog is not available.
-# * "watchdog" : Force Streamlit to use the watchdog module.
-# * "poll" : Force Streamlit to always use polling.
-# * "none" : Streamlit will not watch files.
-
-# Default: "auto"
-fileWatcherType = "auto"
-
-# Symmetric key used to produce signed cookies. If deploying on multiple
-# replicas, this should be set to the same value across all replicas to ensure
-# they all share the same secret.
-
-# Default: randomly generated secret key.
-cookieSecret = "a-random-key-appears-here"
-
-# If false, will attempt to open a browser window on start.
-
-# Default: false unless (1) we are on a Linux box where DISPLAY is unset, or
-# (2) we are running in the Streamlit Atom plugin.
-# headless = false
-
-# Automatically rerun script when the file is modified on disk.
-
-# Default: false
-runOnSave = false
-
-# The address where the server will listen for client and browser
-# connections. Use this if you want to bind the server to a specific address.
-# If set, the server will only be accessible from this address, and not from
-# any aliases (like localhost).
-
-# Default: (unset)
-# address =
-
-# The port where the server will listen for browser connections.
-
-# Default: 8501
-port = 8501
-
-# The base path for the URL where Streamlit should be served from.
-
-# Default: ""
-baseUrlPath = ""
-
-# Enables support for Cross-Origin Resource Sharing (CORS) protection, for
-# added security.
-
-# Due to conflicts between CORS and XSRF, if `server.enableXsrfProtection` is
-# on and `server.enableCORS` is off at the same time, we will prioritize
-# `server.enableXsrfProtection`.
-
-# Default: true
-enableCORS = true
-
-# Enables support for Cross-Site Request Forgery (XSRF) protection, for added
-# security.
-
-# Due to conflicts between CORS and XSRF, if `server.enableXsrfProtection` is
-# on and `server.enableCORS` is off at the same time, we will prioritize
-# `server.enableXsrfProtection`.
-
-# Default: true
-enableXsrfProtection = true
-
-# Max size, in megabytes, for files uploaded with the file_uploader.
-
-# Default: 200
-maxUploadSize = 200
-
-# Max size, in megabytes, of messages that can be sent via the WebSocket
-# connection.
-
-# Default: 200
-maxMessageSize = 200
-
-# Enables support for websocket compression.
-
-# Default: false
-enableWebsocketCompression = false
-
-# Enable serving files from a `static` directory in the running app's
-# directory.
-
-# Default: false
-enableStaticServing = false
-
-# Server certificate file for connecting via HTTPS.
-# Must be set at the same time as "server.sslKeyFile".
-
-# ['DO NOT USE THIS OPTION IN A PRODUCTION ENVIRONMENT. It has not gone through
-# security audits or performance tests. For the production environment, we
-# recommend performing SSL termination by the load balancer or the reverse
-# proxy.']
-# sslCertFile =
-
-# Cryptographic key file for connecting via HTTPS.
-# Must be set at the same time as "server.sslCertFile".
-
-# ['DO NOT USE THIS OPTION IN A PRODUCTION ENVIRONMENT. It has not gone through
-# security audits or performance tests. For the production environment, we
-# recommend performing SSL termination by the load balancer or the reverse
-# proxy.']
-# sslKeyFile =
-
-[browser]
-
-# Internet address where users should point their browsers in order to
-# connect to the app. Can be IP address or DNS name and path.
-
-# This is used to:
-# - Set the correct URL for CORS and XSRF protection purposes.
-# - Show the URL on the terminal
-# - Open the browser
-
-# Default: "localhost"
-serverAddress = "localhost"
-
-# Whether to send usage statistics to Streamlit.
-
-# Default: true
-gatherUsageStats = true
-
-# Port where users should point their browsers in order to connect to the
-# app.
-
-# This is used to:
-# - Set the correct URL for CORS and XSRF protection purposes.
-# - Show the URL on the terminal
-# - Open the browser
-
-# Default: whatever value is set in server.port.
-serverPort = 8501
-
-[mapbox]
-
-# Configure Streamlit to use a custom Mapbox
-# token for elements like st.pydeck_chart and st.map.
-# To get a token for yourself, create an account at
-# https://mapbox.com. It's free (for moderate usage levels)!
-
-# Default: ""
-token = ""
-
-[deprecation]
-
-# Set to false to disable the deprecation warning for the file uploader
-# encoding.
-
-# Default: true
-showfileUploaderEncoding = true
-
-# Set to false to disable the deprecation warning for using the global pyplot
-# instance.
-
-# Default: true
-showPyplotGlobalUse = true
-
-[theme]
-
-# The preset Streamlit theme that your custom theme inherits from.
-# One of "light" or "dark".
-# base =
-
-# Primary accent color for interactive elements.
-# primaryColor =
-
-# Background color for the main content area.
-# backgroundColor =
-
-# Background color used for the sidebar and most interactive widgets.
-# secondaryBackgroundColor =
-
-# Color used for almost all text.
-# textColor =
-
-# Font family for all text in the app, except code blocks. One of "sans serif",
-# "serif", or "monospace".
-# font =
-```
-
-
diff --git a/data/library/advanced-features/connecting-to-data.md b/data/library/advanced-features/connecting-to-data.md
deleted file mode 100644
index a21506d53..000000000
--- a/data/library/advanced-features/connecting-to-data.md
+++ /dev/null
@@ -1,266 +0,0 @@
----
-title: Connecting to data
-slug: /library/advanced-features/connecting-to-data
----
-
-# Connecting to data
-
-Most Streamlit apps need some kind of data or API access to be useful - either retrieving data to view or saving the results of some user action. This data or API is often part of some remote service, database, or other data source.
-
-**Anything you can do with Python, including data connections, will generally work in Streamlit**. Streamlit's [tutorials](/knowledge-base/tutorials/databases) are a great starting place for many data sources. However:
-
-- Connecting to data in a Python application is often tedious and annoying.
-- There are specific considerations for connecting to data from streamlit apps, such as caching and secrets management.
-
-**Streamlit provides [`st.experimental_connection()`](/library/api-reference/connections/st.experimental_connection) to more easily connect your Streamlit apps to data and APIs with just a few lines of code**. This page provides a basic example of using the feature and then focuses on advanced usage.
-
-For a comprehensive overview of this feature, check out this video tutorial by Joshua Carroll, Streamlit's Product Manager for Developer Experience. You'll learn about the feature's utility in creating and managing data connections within your apps by using real-world examples.
-
-
-
-## Basic usage
-
-For basic startup and usage examples, read up on the relevant [data source tutorial](/knowledge-base/tutorials/databases) or our [blog post introducing st.experimental_connection](https://blog.streamlit.io/introducing-st-experimental_connection/). Streamlit has built-in connections to SQL dialects and Snowflake Snowpark. We also maintain installable connections for [Cloud File Storage](https://github.com/streamlit/files-connection) and [Google Sheets](https://github.com/streamlit/gsheets-connection).
-
-If you are just starting, the best way to learn is to pick a data source you can access and get a minimal example working from one of the pages above 👆. Here, we will provide an ultra-minimal usage example for using a SQLite database. From there, the rest of this page will focus on advanced usage.
-
-### A simple starting point - using a local SQLite database
-
-A [local SQLite database](https://sqlite.org/index.html) could be useful for your app's semi-persistent data storage.
-
-
-
-Community Cloud apps do not guarantee the persistence of local file storage, so the platform may delete data stored using this technique at any time.
-
-
-
-To see the example below running live, check out the interactive demo below:
-
-
-
-#### Step 1: Install prerequisite library - SQLAlchemy
-
-All SQLConnections in Streamlit use SQLAlchemy. For most other SQL dialects, you also need to install the driver. But the [SQLite driver ships with python3](https://docs.python.org/3/library/sqlite3.html), so it isn't necessary.
-
-```bash
-pip install SQLAlchemy==1.4.0
-```
-
-#### Step 2: Set a database URL in your Streamlit secrets.toml file
-
-Create a directory and file `.streamlit/secrets.toml` in the same directory your app will run from. Add the following to the file.
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.pets_db]
-url = "sqlite:///pets.db"
-```
-
-#### Step 3: Use the connection in your app
-
-The following app creates a connection to the database, uses it to create a table and insert some data, then queries the data back and displays it in a data frame.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-# Create the SQL connection to pets_db as specified in your secrets file.
-conn = st.experimental_connection('pets_db', type='sql')
-
-# Insert some data with conn.session.
-with conn.session as s:
- s.execute('CREATE TABLE IF NOT EXISTS pet_owners (person TEXT, pet TEXT);')
- s.execute('DELETE FROM pet_owners;')
- pet_owners = {'jerry': 'fish', 'barbara': 'cat', 'alex': 'puppy'}
- for k in pet_owners:
- s.execute(
- 'INSERT INTO pet_owners (person, pet) VALUES (:owner, :pet);',
- params=dict(owner=k, pet=pet_owners[k])
- )
- s.commit()
-
-# Query and display the data you inserted
-pet_owners = conn.query('select * from pet_owners')
-st.dataframe(pet_owners)
-```
-
-In this example, we didn't set a `ttl=` value on the call to [`conn.query()`](/library/api-reference/connections/st.connections.sqlconnection#sqlconnectionquery), meaning Streamlit caches the result indefinitely as long as the app server runs.
-
-Now, on to more advanced topics! 🚀
-
-## Advanced topics
-
-### Global secrets, managing multiple apps and multiple data stores
-
-Streamlit [supports a global secrets file](/library/advanced-features/secrets-management) specified in the user's home directory, such as `~/.streamlit/secrets.toml`. If you build or manage multiple apps, we recommend using a global credential or secret file for local development across apps. With this approach, you only need to set up and manage your credentials in one place, and connecting a new app to your existing data sources is effectively a one-liner. It also reduces the risk of accidentally checking in your credentials to git since they don't need to exist in the project repository.
-
-For cases where you have multiple similar data sources that you connect to during local development (such as a local vs. staging database), you can define different connection sections in your secrets or credentials file for different environments and then decide which to use at runtime. `st.experimental_connection` supports this with the _`name=env:`_ syntax.
-
-E.g., say I have a local and a staging MySQL database and want to connect my app to either at different times. I could create a global secrets file like this:
-
-```toml
-# ~/.streamlit/secrets.toml
-
-[connections.local]
-url = "mysql://me:****@localhost:3306/local_db"
-
-[connections.staging]
-url = "mysql://jdoe:******@staging.acmecorp.com:3306/staging_db"
-```
-
-Then I can configure my app connection to take its name from a specified environment variable
-
-```python
-# streamlit_app.py
-import streamlit as st
-
-conn = st.experimental_connection("env:DB_CONN", "sql")
-df = conn.query("select * from mytable")
-# ...
-```
-
-Now I can specify whether to connect to local or staging at runtime by setting the `DB_CONN` environment variable.
-
-```bash
-# connect to local
-DB_CONN=local streamlit run streamlit_app.py
-
-# connect to staging
-DB_CONN=staging streamlit run streamlit_app.py
-```
-
-### Advanced SQLConnection configuration
-
-The [SQLConnection](/library/api-reference/connections/st.connections.sqlconnection) configuration uses SQLAlchemy `create_engine()` function. It will take a single URL argument or attempt to construct a URL from several parts (username, database, host, and so on) using [`SQLAlchemy.engine.URL.create()`](https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.engine.URL.create).
-
-Several popular SQLAlchemy dialects, such as Snowflake and Google BigQuery, can be configured using additional arguments to `create_engine()` besides the URL. These can be passed as `**kwargs` to the [st.experimental_connection](/library/api-reference/connections/st.experimental_connection) call directly or specified in an additional secrets section called `create_engine_kwargs`.
-
-E.g. snowflake-sqlalchemy takes an additional [`connect_args`](https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.create_engine.params.connect_args) argument as a dictionary for configuration that isn’t supported in the URL. These could be specified as follows:
-
-```toml
-# .streamlit/secrets.toml
-
-[connections.snowflake]
-url = "snowflake://@/"
-
-[connections.snowflake.create_engine_kwargs.connect_args]
-authenticator = "externalbrowser"
-warehouse = "xxx"
-role = "xxx"
-```
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-# url and connect_args from secrets.toml above are picked up and used here
-conn = st.experimental_connection("snowflake", "sql")
-# ...
-```
-
-Alternatively, this could be specified entirely in `**kwargs`.
-
-```python
-# streamlit_app.py
-
-import streamlit as st
-
-# secrets.toml is not needed
-conn = st.experimental_connection(
- "snowflake",
- "sql",
- url = "snowflake://@/",
- connect_args = dict(
- authenticator = "externalbrowser",
- warehouse = "xxx",
- role = "xxx",
- )
-)
-# ...
-```
-
-You can also provide both kwargs and secrets.toml values, and they will be merged (typically, kwargs take precedence).
-
-### Connection considerations in frequently used or long-running apps
-
-By default, connection objects are cached without expiration using [`st.cache_resource`](/library/api-reference/performance/st.cache_resource). In most cases this is desired. You can do `st.experimental_connection('myconn', type=MyConnection, ttl=)` if you want the connection object to expire after some time.
-
-Many connection types are expected to be long-running or completely stateless, so expiration is unnecessary. Suppose a connection becomes stale (such as a cached token expiring or a server-side connection being closed). In that case, every connection has a `reset()` method, which will invalidate the cached version and cause Streamlit to recreate the connection the next time it is retrieved
-
-Convenience methods like `query()` and `read()` will typically cache results by default using [`st.cache_data`](/library/api-reference/performance/st.cache_data) without an expiration. When an app can run many different read operations with large results, it can cause high memory usage over time and results to become stale in a long-running app, the same as with any other usage of `st.cache_data`. For production use cases, we recommend setting an appropriate `ttl` on these read operations, such as `conn.read('path/to/file', ttl="1d")`. Refer to [Caching](/library/advanced-features/caching) for more information.
-
-For apps that could get significant concurrent usage, ensure that you understand any thread safety implications of your connection, particularly when using a connection built by a third party. Connections built by Streamlit should provide thread-safe operations by default.
-
-### Build your own connection
-
-Building your own basic connection implementation using an existing driver or SDK is quite straightforward in most cases. However, you can add more complex functionality with further effort. This custom implementation can be a great way to extend support to a new data source and contribute to the Streamlit ecosystem.
-
-Maintaining a tailored internal Connection implementation across many apps can be a powerful practice for organizations with frequently used access patterns and data sources.
-
-Check out the [Build your own Connection page](https://experimental-connection.streamlit.app/Build_your_own) in the st.experimental connection demo app below for a quick tutorial and working implementation. This demo builds a minimal but very functional Connection on top of DuckDB.
-
-
-
-The typical steps are:
-
-1. Declare the Connection class, extending [`ExperimentalBaseConnection`](/library/api-reference/connections/st.connections.experimentalbaseconnection) with the type parameter bound to the underlying connection object:
-
- ```python
- from streamlit.connections import ExperimentalBaseConnection
- import duckdb
-
- class DuckDBConnection(ExperimentalBaseConnection[duckdb.DuckDBPyConnection])
- ```
-
-2. Implement the `_connect` method that reads any kwargs, external config/credential locations, and Streamlit secrets to initialize the underlying connection:
-
- ```python
- def _connect(self, **kwargs) -> duckdb.DuckDBPyConnection:
- if 'database' in kwargs:
- db = kwargs.pop('database')
- else:
- db = self._secrets['database']
- return duckdb.connect(database=db, **kwargs)
- ```
-
-3. Add useful helper methods that make sense for your connection (wrapping them in `st.cache_data` where caching is desired)
-
-### Connection-building best practices
-
-We recommend applying the following best practices to make your Connection consistent with the Connections built into Streamlit and the wider Streamlit ecosystem. These practices are especially important for Connections that you intend to distribute publicly.
-
-1. **Extend existing drivers or SDKs, and default to semantics that makes sense for their existing users.**
-
- You should rarely need to implement complex data access logic from scratch when building a Connection. Use existing popular Python drivers and clients whenever possible. Doing so makes your Connection easier to maintain, more secure, and enables users to get the latest features. E.g. [SQLConnection](/library/api-reference/connections/st.connections.sqlconnection) extends SQLAlchemy, [FileConnection](https://github.com/streamlit/files-connection) extends [fsspec](https://filesystem-spec.readthedocs.io/en/latest/), [GsheetsConnection](https://github.com/streamlit/gsheets-connection) extends [gspread](https://docs.gspread.org/en/latest/), etc.
-
- Consider using access patterns, method/argument naming, and return values that are consistent with the underlying package and familiar to existing users of that package.
-
-2. **Intuitive, easy to use read methods.**
-
- Much of the power of st.experimental_connection is providing intuitive, easy-to-use read methods that enable app developers to get started quickly. Most connections should expose at least one read method that is:
-
- - Named with a simple verb, like `read()`, `query()`, or `get()`
- - Wrapped by `st.cache_data` by default, with at least `ttl=` argument supported
- - If the result is in a tabular format, it returns a pandas DataFrame
- - Provides commonly used keyword arguments (such as paging or formatting) with sensible defaults - ideally, the common case requires only 1-2 arguments.
-
-3. **Config, secrets, and precedence in `_connect` method.**
-
- Every Connection should support commonly used connection parameters provided via Streamlit secrets and keyword arguments. The names should match the ones used when initializing or configuring the underlying package.
-
- Additionally, where relevant, Connections should support data source specific configuration through existing standard environment variables or config / credential files. In many cases, the underlying package provides constructors or factory functions that already handle this easily.
-
- When you can specify the same connection parameters in multiple places, we recommend using the following precedence order when possible (highest to lowest):
-
- - Keyword arguments specified in the code
- - Streamlit secrets
- - data source specific configuration (if relevant)
-
-4. **Handling thread safety and stale connections.**
-
- Connections should provide thread-safe operations when practical (which should be most of the time) and clearly document any considerations around this. Most underlying drivers or SDKs should provide thread-safe objects or methods - use these when possible.
-
- If the underlying driver or SDK has a risk of stateful connection objects becoming stale or invalid, consider building a low impact health check or reset/retry pattern into the access methods. The SQLConnection built into Streamlit has a good example of this pattern using [tenacity](https://tenacity.readthedocs.io/) and the built-in [Connection.reset()](/library/api-reference/connections/st.connections.sqlconnection#sqlconnectionreset) method. An alternate approach is to encourage developers to set an appropriate TTL on the `st.experimental_connection()` call to ensure it periodically reinitializes the connection object.
diff --git a/data/library/advanced-features/dataframes.md b/data/library/advanced-features/dataframes.md
deleted file mode 100644
index 048ddbdbd..000000000
--- a/data/library/advanced-features/dataframes.md
+++ /dev/null
@@ -1,303 +0,0 @@
----
-title: Dataframes
-slug: /library/advanced-features/dataframes
----
-
-# Dataframes
-
-Dataframes are a great way to display and edit data in a tabular format. Working with Pandas DataFrames and other tabular data structures is key to data science workflows. If developers and data scientists want to display this data in Streamlit, they have multiple options: `st.dataframe` and `st.data_editor`. If you want to solely display data in a table-like UI, [st.dataframe](/library/api-reference/data/st.dataframe) is the way to go. If you want to interactively edit data, use [st.data_editor](/library/api-reference/data/st.data_editor). We explore the use cases and advantages of each option in the following sections.
-
-## Display dataframes with st.dataframe
-
-Streamlit can display dataframes in a table-like UI via `st.dataframe` :
-
-```python
-import streamlit as st
-import pandas as pd
-
-df = pd.DataFrame(
- [
- {"command": "st.selectbox", "rating": 4, "is_widget": True},
- {"command": "st.balloons", "rating": 5, "is_widget": False},
- {"command": "st.time_input", "rating": 3, "is_widget": True},
- ]
-)
-
-st.dataframe(df, use_container_width=True)
-```
-
-
-
-## Additional UI features
-
-`st.dataframe` also provides some additional functionality by using [glide-data-grid](https://github.com/glideapps/glide-data-grid) under the hood:
-
-- **Column sorting**: sort columns by clicking on their headers.
-- **Column resizing**: resize columns by dragging and dropping column header borders.
-- **Table resizing**: resize tables by dragging and dropping the bottom right corner.
-- **Search**: search through data by clicking a table, using hotkeys (`⌘ Cmd + F` or `Ctrl + F`) to bring up the search bar, and using the search bar to filter data.
-- **Copy to clipboard**: select one or multiple cells, copy them to the clipboard and paste them into your favorite spreadsheet software.
-
-
-
-Try out all the UI features using the embedded app from the prior section.
-
-In addition to Pandas DataFrames, `st.dataframe` also supports other common Python types, e.g., list, dict, or numpy array. It also supports [Snowpark](https://docs.snowflake.com/en/developer-guide/snowpark/index) and [PySpark](https://spark.apache.org/docs/latest/api/python/) DataFrames, which allow you to lazily evaluate and pull data from databases. This can be useful for working with large datasets.
-
-## Edit data with st.data_editor
-
-Streamlit supports editable dataframes via the `st.data_editor` command. Check out its API in [st.data_editor](/library/api-reference/data/st.data_editor). It shows the dataframe in a table, similar to `st.dataframe`. But in contrast to `st.dataframe`, this table isn't static! The user can click on cells and edit them. The edited data is then returned on the Python side. Here's an example:
-
-```python
-df = pd.DataFrame(
- [
- {"command": "st.selectbox", "rating": 4, "is_widget": True},
- {"command": "st.balloons", "rating": 5, "is_widget": False},
- {"command": "st.time_input", "rating": 3, "is_widget": True},
- ]
-)
-
-df = load_data()
-edited_df = st.data_editor(df) # 👈 An editable dataframe
-
-favorite_command = edited_df.loc[edited_df["rating"].idxmax()]["command"]
-st.markdown(f"Your favorite command is **{favorite_command}** 🎈")
-```
-
-
-
-
-
-
-
-Try it out by double-clicking on any cell. You'll notice you can edit all cell values. Try editing the values in the rating column and observe how the text output at the bottom changes:
-
-
-
-`st.data_editor` also supports a few additional things:
-
-- [Copy and paste support](#copy-and-paste-support) from and to Excel and Google Sheets.
-- [Add and delete rows](#add-and-delete-rows). You can do this by setting `num_rows= "dynamic"` when calling `st.data_editor`. This will allow users to add and delete rows as needed.
-- [Access edited data](#access-edited-data). Only access the individual edits instead of the entire edited data structure via session state.
-- [Bulk edits](#bulk-edits) (similar to Excel, just drag a handle to edit neighboring cells).
-- [Automatic input validation](#automatic-input-validation), a strong data type support. e.g. There's no way to enter letters into a number cell and many other configurable input validation options. e.g. min-/max-value.
-- [Edit common data structures](#edit-common-data-structures) such as lists, dicts, NumPy ndarray, etc.
-
-### Copy and paste support
-
-The data editor supports pasting in tabular data from Google Sheets, Excel, Notion, and many other similar tools. You can also copy-paste data between `st.data_editor` instances. This functionality, powered by the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API), can be a huge time saver for users who need to work with data across multiple platforms. To try it out:
-
-1. Copy data from [this Google Sheets document](https://docs.google.com/spreadsheets/d/1Z0zd-5dF_HfqUaDDq4BWAOnsdlGCjkbTNwDZMBQ1dOY/edit?usp=sharing) to clipboard
-2. Select any cell in the `name` column of the table below and paste it in (via `ctrl/cmd + v`).
-
-
-
-
-
-
-
-
-
-
-
-Every cell of the pasted data will be evaluated individually and inserted into the cells if the data is compatible with the column type. E.g., pasting in non-numerical text data into a number column will be ignored.
-
-
-
-Did you notice that although the initial dataframe had just five rows, pasting all those rows from the spreadsheet added additional rows to the dataframe? 👀 Let's find out how that works in the next section.
-
-
-
-If you embed your apps with iframes, you'll need to allow the iframe to access the clipboard if you want to use the copy-paste functionality. To do so, give the iframe [`clipboard-write`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write) and [`clipboard-read`](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read) permissions. E.g.
-
-```javascript
-
-```
-
-As developers, ensure the app is served with a valid, trusted certificate when using TLS. If users encounter issues with copying and pasting data, direct them to check if their browser has activated clipboard access permissions for the Streamlit application, either when prompted or through the browser's site settings.
-
-
-
-### Add and delete rows
-
-With `st.data_editor`, viewers can add or delete rows via the table UI. This mode can be activated by setting the `num_rows` parameter to `"dynamic"`. E.g.
-
-```python
-edited_df = st.data_editor(df, num_rows="dynamic")
-```
-
-- To add new rows, scroll to the bottom-most row and click on the “+" sign in any cell.
-- To delete rows, select one or more rows and press the `delete` key on your keyboard.
-
-
-
-
-
-
-
-
-
-### Access edited data
-
-Sometimes, it is more convenient to know which cells have been changed rather than getting the entire edited dataframe back. Streamlit makes this easy through the use of [session state](https://docs.streamlit.io/library/advanced-features/session-state). If a `key` parameter is set, Streamlit will store any changes made to the dataframe in the session state.
-
-This snippet shows how you can access changed data using session state:
-
-```python
-st.data_editor(df, key="data_editor") # 👈 Set a key
-st.write("Here's the session state:")
-st.write(st.session_state["data_editor"]) # 👈 Access the edited data
-```
-
-In this code snippet, the `key` parameter is set to `"data_editor"`. Any changes made to the data in the `st.data_editor` instance will be tracked by Streamlit and stored in session state under the key `"data_editor"`.
-
-After the data editor is created, the contents of the `"data_editor"` key in session state are printed to the screen using `st.write(st.session_state["data_editor"])`. This allows you to see the changes made to the original dataframe without having to return the entire dataframe from the data editor.
-
-This can be useful when working with large dataframes and you only need to know which cells have changed, rather than the entire edited dataframe.
-
-
-
-
-
-
-
-Use all we've learned so far and apply them to the above embedded app. Try editing cells, adding new rows, and deleting rows.
-
-
-
-Notice how edits to the table are reflected in session state: when you make any edits, a rerun is triggered which sends the edits to the backend via `st.data_editor`'s keyed widget state. Its widget state is a JSON object containing three properties: **edited_rows**, **added_rows**, and **deleted rows:**.
-
-
-
-When going from `st.experimental_data_editor` to `st.data_editor` in 1.23.0, the data editor's representation in `st.session_state` was changed. The `edited_cells` dictionary is now called `edited_rows` and uses a different format (`{0: {"column name": "edited value"}}` instead of `{"0:1": "edited value"}`). You may need to adjust the code if your app uses `st.experimental_data_editor` in combination with `st.session_state`."
-
-
-
-- `edited_rows` is a dictionary containing all edits. Keys are zero-based row indices and values are dictionaries that map column names to edits (e.g. `{0: {"col1": ..., "col2": ...}}`).
-- `added_rows` is a list of newly added rows. Each value is a dictionary with the same format as above (e.g. `[{"col1": ..., "col2": ...}]`).
-- `deleted_rows` is a list of row numbers that have been deleted from the table (e.g. `[0, 2]`).
-
-### Bulk edits
-
-The data editor includes a feature that allows for bulk editing of cells. Similar to Excel, you can drag a handle across a selection of cells to edit their values in bulk. You can even apply commonly used [keyboard shortcuts](https://github.com/glideapps/glide-data-grid/blob/main/packages/core/API.md#keybindings) in spreadsheet software. This is useful when you need to make the same change across multiple cells, rather than editing each cell individually:
-
-
-
-### Edit common data structures
-
-Editing doesn't just work for Pandas DataFrames! You can also edit lists, tuples, sets, dictionaries, NumPy arrays, or Snowpark & PySpark DataFrames. Most data types will be returned in their original format. But some types (e.g. Snowpark and PySpark) are converted to Pandas DataFrames. To learn about all the supported types, read the [st.data_editor](/library/api-reference/data/st.data_editor) API.
-
-E.g. you can easily let the user add items to a list:
-
-```python
-edited_list = st.data_editor(["red", "green", "blue"], num_rows= "dynamic")
-st.write("Here are all the colors you entered:")
-st.write(edited_list)
-```
-
-Or numpy arrays:
-
-```python
-import numpy as np
-
-st.data_editor(np.array([
- ["st.text_area", "widget", 4.92],
- ["st.markdown", "element", 47.22]
-]))
-```
-
-Or lists of records:
-
-```python
-st.data_editor([
- {"name": "st.text_area", "type": "widget"},
- {"name": "st.markdown", "type": "element"},
-])
-```
-
-Or dictionaries and many more types!
-
-```python
-st.data_editor({
- "st.text_area": "widget",
- "st.markdown": "element"
-})
-```
-
-### Automatic input validation
-
-The data editor includes automatic input validation to help prevent errors when editing cells. For example, if you have a column that contains numerical data, the input field will automatically restrict the user to only entering numerical data. This helps to prevent errors that could occur if the user were to accidentally enter a non-numerical value. Additional input validation can be configured through the [Column configuration API](/library/api-reference/data/st.column_config). Keep reading below for an overview of column configuration, including validation options.
-
-## Configuring columns
-
-You can configure the display and editing behavior of columns in `st.dataframe` and `st.data_editor` via the [Column configuration API](/library/api-reference/data/st.column_config). We have developed the API to let you add images, charts, and clickable URLs in dataframe and data editor columns. Additionally, you can make individual columns editable, set columns as categorical and specify which options they can take, hide the index of the dataframe, and much more.
-
-Column configuration includes the following column types: Text, Number, Checkbox, Selectbox, Date, Time, Datetime, List, Link, Image, Line chart, Bar chart, and Progress. There is also a generic Column option. See the embedded app below to view these different column types. Each column type is individually previewed in the [Column configuration API](/library/api-reference/data/st.column_config) documentation.
-
-
-
-### Format values
-
-A `format` parameter is available in column configuration for [Text](/library/api-reference/data/st.column_config/st.column_config.textcolumn), [Date](/library/api-reference/data/st.column_config/st.column_config.datecolumn), [Time](/library/api-reference/data/st.column_config/st.column_config.timecolumn), and [Datetime](/library/api-reference/data/st.column_config/st.column_config.datetimecolumn) columns. Chart-like columns can also be formatted. [Line chart](/library/api-reference/data/st.column_config/st.column_config.linechartcolumn) and [Bar chart](/library/api-reference/data/st.column_config/st.column_config.barchartcolumn) columns have a `y_min` and `y_max` parameters to set the vertical bounds. For a [Progress column](/library/api-reference/data/st.column_config/st.column_config.progresscolumn), you can declare the horizontal bounds with `min_value` and `max_value`.
-
-### Validate input
-
-When specifying a column configuration, you can declare not only the data type of the column but also value restrictions. All column configuration elements allow you to make a column required with the keyword parameter `required=True`.
-
-For Text and Link columns, you can specify the maximum number of characters with `max_chars` or use regular expressions to validate entries through `validate`. Numerical columns, including Number, Date, Time, and Datetime have `min_value` and `max_value` parameters. Selectbox columns have a configurable list of `options`.
-
-The data type for Number columns is `float` by default. Passing a value of type `int` to any of `min_value`, `max_value`, `step`, or `default` will set the type for the column as `int`.
-
-### Configure an empty dataframe
-
-You can use `st.data_editor` to collect tabular input from a user. When starting from an empty dataframe, default column types are text. Use column configuration to specify the data types you want to collect from users.
-
-```python
-import streamlit as st
-import pandas as pd
-
-df = pd.DataFrame(columns=['name','age','color'])
-colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
-config = {
- 'name' : st.column_config.TextColumn('Full Name (required)', width='large', required=True),
- 'age' : st.column_config.NumberColumn('Age (years)', min_value=0, max_value=122),
- 'color' : st.column_config.SelectboxColumn('Favorite Color', options=colors)
-}
-
-result = st.data_editor(df, column_config = config, num_rows='dynamic')
-
-if st.button('Get results'):
- st.write(result)
-```
-
-
-
-## Additional formatting options
-
-In addition to column configuration, `st.dataframe` and `st.data_editor` have a few more parameters to customize the display of your dataframe.
-
-* `hide_index` : Set to `True` to hide the dataframe's index.
-* `column_order` : Pass a list of column labels to specify the order of display.
-* `disabled` : Pass a list of column labels to disable them from editing. This let's you avoid disabling them individually.
-
-## Handling large datasets
-
-`st.dataframe` and `st.data_editor` have been designed to theoretically handle tables with millions of rows thanks to their highly performant implementation using the glide-data-grid library and HTML canvas. However, the maximum amount of data that an app can realistically handle will depend on several other factors, including:
-
-1. The maximum size of WebSocket messages: Streamlit's WebSocket messages are configurable via the `server.maxMessageSize` [config option](https://docs.streamlit.io/library/advanced-features/configuration#view-all-configuration-options), which limits the amount of data that can be transferred via the WebSocket connection at once.
-2. The server memory: The amount of data that your app can handle will also depend on the amount of memory available on your server. If the server's memory is exceeded, the app may become slow or unresponsive.
-3. The user's browser memory: Since all the data needs to be transferred to the user's browser for rendering, the amount of memory available on the user's device can also affect the app's performance. If the browser's memory is exceeded, it may crash or become unresponsive.
-
-In addition to these factors, a slow network connection can also significantly slow down apps that handle large datasets.
-
-When handling large datasets with more than 150,000 rows, Streamlit applies additional optimizations and disables column sorting. This can help to reduce the amount of data that needs to be processed at once and improve the app's performance.
-
-## Limitations
-
-While Streamlit's data editing capabilities offer a lot of functionality, there are some limitations to be aware of:
-
-- Editing is enabled for a limited set of column types ([TextColumn](/library/api-reference/data/st.column_config/st.column_config.textcolumn), [NumberColumn](/library/api-reference/data/st.column_config/st.column_config.numbercolumn), [LinkColumn](/library/api-reference/data/st.column_config/st.column_config.linkcolumn), [CheckboxColumn](/library/api-reference/data/st.column_config/st.column_config.checkboxcolumn), [SelectboxColumn](/library/api-reference/data/st.column_config/st.column_config.selectboxcolumn), [DateColumn](/library/api-reference/data/st.column_config/st.column_config.datecolumn), [TimeColumn](/library/api-reference/data/st.column_config/st.column_config.timecolumn), and [DatetimeColumn](/library/api-reference/data/st.column_config/st.column_config.datetimecolumn)). We are actively working on supporting editing for other column types as well, such as images, lists, and charts.
-- Editing of Pandas DataFrames only supports the following index types: `RangeIndex`, (string) `Index`, `Float64Index`, `Int64Index`, and `UInt64Index`.
-- Some actions like deleting rows or searching data can only be triggered via keyboard hotkeys.
-
-We are working to fix the above limitations in future releases, so keep an eye out for updates.
diff --git a/data/library/advanced-features/forms.md b/data/library/advanced-features/forms.md
deleted file mode 100644
index 16686035b..000000000
--- a/data/library/advanced-features/forms.md
+++ /dev/null
@@ -1,227 +0,0 @@
----
-title: Using forms
-slug: /library/advanced-features/forms
----
-
-# Using forms
-
-When you don't want to rerun your script with each input made by a user, [`st.form`](/library/api-reference/control-flow/st.form) is here to help! Forms make it easy to batch user input into a single rerun. This guide to using forms provides examples and explains how users interact with forms.
-
-## Example
-
-In the following example, a user can set multiple parameters to update the map. As the user changes the parameters, the script will not rerun and the map will not update. When the user submits the form with the button labeled "**Update map**", the script reruns and the map updates.
-
-If at any time the user clicks "**Generate new points**" which is outside of the form, the script will rerun. If the user has any unsubmitted changes within the form, these will _not_ be sent with the rerun. All changes made to a form will only be sent to the Python backend when the form itself is submitted.
-
-
-
-```python
-import streamlit as st
-import pandas as pd
-import numpy as np
-
-def get_data():
- df = pd.DataFrame({
- "lat": np.random.randn(200) / 50 + 37.76,
- "lon": np.random.randn(200) / 50 + -122.4,
- "team": ['A','B']*100
- })
- return df
-
-if st.button('Generate new points'):
- st.session_state.df = get_data()
-if 'df' not in st.session_state:
- st.session_state.df = get_data()
-df = st.session_state.df
-
-with st.form("my_form"):
- header = st.columns([1,2,2])
- header[0].subheader('Color')
- header[1].subheader('Opacity')
- header[2].subheader('Size')
-
- row1 = st.columns([1,2,2])
- colorA = row1[0].color_picker('Team A', '#0000FF')
- opacityA = row1[1].slider('A opacity', 20, 100, 50, label_visibility='hidden')
- sizeA = row1[2].slider('A size', 50, 200, 100, step=10, label_visibility='hidden')
-
- row2 = st.columns([1,2,2])
- colorB = row2[0].color_picker('Team B', '#FF0000')
- opacityB = row2[1].slider('B opacity', 20, 100, 50, label_visibility='hidden')
- sizeB = row2[2].slider('B size', 50, 200, 100, step=10, label_visibility='hidden')
-
- st.form_submit_button('Update map')
-
-alphaA = int(opacityA*255/100)
-alphaB = int(opacityB*255/100)
-
-df['color'] = np.where(df.team=='A',colorA+f'{alphaA:02x}',colorB+f'{alphaB:02x}')
-df['size'] = np.where(df.team=='A',sizeA, sizeB)
-
-st.map(df, size='size', color='color')
-```
-
-
-
-
-
-## User interaction
-
-If a widget is not in a form, that widget will trigger a script rerun whenever a user changes its value. For widgets with keyed input (`st.number_input`, `st.text_input`, `st.text_area`), a new value triggers a rerun when the user clicks or tabs out of the widget. A user can also submit a change by pressing `Enter` while thier cursor is active in the widget.
-
-On the other hand if a widget is inside of a form, the script will not rerun when a user clicks or tabs out of that widget. For widgets inside a form, the script will rerun when the form is submitted and all widgets within the form will send their updated values to the Python backend.
-
-
-
-A user can submit a form using **Enter** on their keyboard if their cursor active in a widget that accepts keyed input. Within `st.number_input` and `st.text_input` a user presses **Enter** to submit the form. Within `st.text_area` a user presses **Ctrl+Enter**/**⌘+Enter** to submit the form.
-
-
-
-## Widget values
-
-Before a form is submitted, all widgets within that form will have default values, just like widgets outside of a form have default values.
-
-```python
-import streamlit as st
-
-with st.form("my_form"):
- st.write("Inside the form")
- my_number = st.slider('Pick a number', 1, 10)
- my_color = st.selectbox('Pick a color', ['red','orange','green','blue','violet'])
- st.form_submit_button('Submit my picks')
-
-# This is outside the form
-st.write(my_number)
-st.write(my_color)
-```
-
-
-
-## Forms are containers
-
-When `st.form` is called, a container is created on the frontend. You can write to that container like you do with other [container elements](/library/api-reference/layout). That is, you can use Python's `with` statement as shown in the example above, or you can assign the form container to a variable and call methods on it directly. Additionally, you can place `st.form_submit_button` anywhere in the form container.
-
-```python
-import streamlit as st
-
-animal = st.form('my_animal')
-
-# This is writing directly to the main body. Since the form container is
-# defined above, this will appear below everything written in the form.
-sound = st.selectbox('Sounds like', ['meow','woof','squeak','tweet'])
-
-# These methods called on the form container, so they appear inside the form.
-submit = animal.form_submit_button(f'Say it with {sound}!')
-sentence = animal.text_input('Your sentence:', 'Where\'s the tuna?')
-say_it = sentence.rstrip('.,!?') + f', {sound}!'
-if submit:
- animal.subheader(say_it)
-else:
- animal.subheader(' ')
-```
-
-
-
-## Processing form submissions
-
-The purpose of a form is to override the default behavior of Streamlit which reruns a script as soon as the user makes a change. For widgets outside of a form, the logical flow is:
-
-1. The user changes a widget's value on the frontend.
-2. The widget's value in `st.session_state` and in the Python backend (server) is updated.
-3. The script rerun begins.
-4. If the widget has a callback, it is executed as a prefix to the page rerun.
-5. When the updated widget's function is executed during the rerun, it outputs the new value.
-
-For widgets inside a form, any changes made by a user (step 1) do not get passed to the Python backend (step 2) until the form is submitted. Furthermore, the only widget inside a form that can have a callback function is the `st.form_submit_button`. If you need to execute a process using newly submitted values, you have three major patterns for doing so.
-
-### Execute the process after the form
-
-If you need to execute a one-time process as a result of a form submission, you can condition that process on the `st.form_submit_button` and execute it after the form. If you need results from your process to display above the form, you can use containers to control where the form displays relative to your output.
-
-```python
-import streamlit as st
-
-col1,col2 = st.columns([1,2])
-col1.title('Sum:')
-
-with st.form('addition'):
- a = st.number_input('a')
- b = st.number_input('b')
- submit = st.form_submit_button('add')
-
-if submit:
- col2.title(f'{a+b:.2f}')
-```
-
-
-
-### Use a callback with session state
-
-You can use a callback to execute a process as a prefix to the script rerunning.
-
-
-
-When processing newly updated values within a callback, do not pass those values to the callback directly through the `args` or `kwargs` parameters. You need to assign a key to any widget whose value you use within the callback. If you look up the value of that widget from `st.session_state` within the body of the callback, you will be able to access the newly submitted value. See the example below.
-
-
-
-```python
-import streamlit as st
-
-if 'sum' not in st.session_state:
- st.session_state.sum = ''
-
-def sum():
- result = st.session_state.a + st.session_state.b
- st.session_state.sum = result
-
-col1,col2 = st.columns(2)
-col1.title('Sum:')
-if isinstance(st.session_state.sum, float):
- col2.title(f'{st.session_state.sum:.2f}')
-
-with st.form('addition'):
- st.number_input('a', key = 'a')
- st.number_input('b', key = 'b')
- st.form_submit_button('add', on_click=sum)
-```
-
-
-
-### Use `st.experimental_rerun`
-
-If your process affects content above your form, another alternative is using an extra rerun. This can be less resource-efficient though, and may be less desirable that the above options.
-
-```python
-import streamlit as st
-
-if 'sum' not in st.session_state:
- st.session_state.sum = ''
-
-col1,col2 = st.columns(2)
-col1.title('Sum:')
-if isinstance(st.session_state.sum, float):
- col2.title(f'{st.session_state.sum:.2f}')
-
-with st.form('addition'):
- a = st.number_input('a')
- b = st.number_input('b')
- submit = st.form_submit_button('add')
-
-# The value of st.session_state.sum is updated at the end of the script rerun,
-# so the displayed value at the top in col2 does not show the new sum. Trigger
-# a second rerun when the form is submitted to update the value above.
-st.session_state.sum = a + b
-if submit:
- st.experimental_rerun()
-```
-
-
-
-## Limitations
-
-* Every form must contain a `st.form_submit_button`.
-* `st.button` and `st.download_button` cannot be added to a form.
-* `st.form` cannot be embedded inside another `st.form`.
-* Callback functions can only be assigned to `st.form_submit_button` within a form; no other widgets in a form can have a callback.
-* Interdependent widgets within a form are unlikely to be particularly useful. If you pass `widget1`'s value into `widget2` when they are both inside a form, then `widget2` will only update when the form is submitted.
diff --git a/data/library/advanced-features/https.md b/data/library/advanced-features/https.md
deleted file mode 100644
index 93a024e26..000000000
--- a/data/library/advanced-features/https.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-title: HTTPS support
-slug: /library/advanced-features/https-support
----
-
-# HTTPS support
-
-Many apps need to be accessed with SSL / [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) protocol or `https://`.
-
-We recommend performing SSL termination in a reverse proxy or load balancer for self-hosted and production use cases, not directly in the app. [Streamlit Community Cloud](/streamlit-community-cloud) uses this approach, and every major cloud and app hosting platform should allow you to configure it and provide extensive documentation. You can find some of these platforms in our [Deployment tutorials](/knowledge-base/tutorials/deploy).
-
-To terminate SSL in your Streamlit app, you must configure `server.sslCertFile` and `server.sslKeyFile`. Learn how to set config options in [Configuration](/library/advanced-features/configuration).
-
-## Details on usage
-
-- The configuration value should be a local file path to a cert file and key file. These must be available at the time the app starts.
-- Both `server.sslCertFile` and `server.sslKeyFile` must be specified. If only one is specified, your app will exit with an error.
-- This feature will not work in Community Cloud. Community Cloud already serves your app with TLS.
-
-
-
-In a production environment, we recommend performing SSL termination by the load balancer or the reverse proxy, not using this option. The use of this option in Streamlit has not gone through extensive security audits or performance tests.
-
-
-
-## Example usage
-
-```toml
-# .streamlit/config.toml
-
-[server]
-sslCertFile = '/path/to/certchain.pem'
-sslKeyFile = '/path/to/private.key'
-```
diff --git a/data/library/advanced-features/index.md b/data/library/advanced-features/index.md
deleted file mode 100644
index cfe19180a..000000000
--- a/data/library/advanced-features/index.md
+++ /dev/null
@@ -1,148 +0,0 @@
----
-title: Advanced features
-slug: /library/advanced-features
----
-
-## Advanced features
-
-This section gives you background on how different parts of Streamlit work.
-
-
-
-
-
-##### ⋮ App menu
-
-Streamlit provides a configurable menu within your app to access convenient tools for developers and viewers. These options can modify the appearance of your app while running.
-
-- [Modify your app's theme while running](/library/advanced-features/app-menu#settings)
-- [Record a screencast of your app](/library/advanced-features/app-menu#record-a-screencast)
-- [Deploy a local app to Streamlit Community Cloud](/library/advanced-features/app-menu#deploy-this-app)
-- [Customize or hide the app menu](/library/advanced-features/app-menu#customize-the-menu)
-
-
-
-
-
-##### Command-line options
-
-When you install Streamlit, a command-line (CLI) tool gets installed as well. The purpose of this tool is to run Streamlit apps, change Streamlit configuration options, and help you diagnose and fix issues.
-
-- [What is the command-line interface (CLI)?](/library/advanced-features/cli#command-line-interface)
-- [How to run Streamlit apps from the CLI?](/library/advanced-features/cli#run-streamlit-apps)
-- [View Streamlit version from the CLI?](/library/advanced-features/cli#view-streamlit-version)
-- [View documentation from the CLI](/library/advanced-features/cli#view-documentation)
-- [Clear cache from the CLI](/library/advanced-features/cli#clear-cache)
-
-
-
-
-
-##### Streamlit configuration
-
-Streamlit provides four different ways to set configuration options. Learn how to use each of them to change the behavior of Streamlit.
-
-- [How to set configuration options?](/library/advanced-features/configuration)
-- [Opt out of telemetry collection](/library/advanced-features/configuration#telemetry)
-- [View all configuration options](/library/advanced-features/configuration#view-all-configuration-options)
-
-
-
-
-
-##### Theming
-
-This section provides examples of how Streamlit page elements are affected by the various theme config options.
-
-- [primaryColor](/library/advanced-features/theming#primarycolor)
-- [backgroundcolor](/library/advanced-features/theming#backgroundcolor)
-- [secondarybackgroundcolor](/library/advanced-features/theming#secondarybackgroundcolor)
-- [textcolor](/library/advanced-features/theming#textcolor)
-- [font](/library/advanced-features/theming#font)
-- [base](/library/advanced-features/theming#base)
-
-
-
-
-
-##### Caching
-
-The Streamlit cache allows your app to stay performant even when loading data from the web, manipulating large datasets, or performing expensive computations. To cache a function in Streamlit, you need to decorate it with one of two decorators: `st.cache_data` and `st.cache_resource`.
-
-- [Minimal example](/library/advanced-features/caching#minimal-example)
-- [Basic usage](/library/advanced-features/caching#basic-usage)
- - [st.cache_data](/library/advanced-features/caching#stcache_data)
- - [st.cache_resource](/library/advanced-features/caching#stcache_resource)
- - [Deciding which caching decorator to use](/library/advanced-features/caching#deciding-which-caching-decorator-to-use)
-- [Advanced usage](/library/advanced-features/caching#advanced-usage)
- - [Excluding input parameters](/library/advanced-features/caching#excluding-input-parameters)
- - [Controlling cache size and duration](/library/advanced-features/caching#controlling-cache-size-and-duration)
- - [Customizing the spinner](/library/advanced-features/caching#customizing-the-spinner)
- - [Using Streamlit commands in cached functions](/library/advanced-features/caching#using-streamlit-commands-in-cached-functions)
- - [Mutation and concurrency issues](/library/advanced-features/caching#mutation-and-concurrency-issues)
-- [Migrating from st.cache](/library/advanced-features/caching#migrating-from-stcache)
-
-
-
-
-
-##### Add statefulness to apps
-
-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.
-
-- [What is Session State?](/library/advanced-features/session-state#what-is-state)
-- [How to initialize Session State items?](/library/advanced-features/session-state#initialization)
-- [How to read and update Session State items?](/library/advanced-features/session-state#reads-and-updates)
-- [How to use callbacks in Session State?](/library/advanced-features/session-state#example-2-session-state-and-callbacks)
-- [How to use `args` and `kwargs` in callbacks?](/library/advanced-features/session-state#example-3-use-args-and-kwargs-in-callbacks)
-- [How to use callbacks in forms?](/library/advanced-features/session-state#example-4-forms-and-callbacks)
-- [How is Session State related to Widget State?](/library/advanced-features/session-state#session-state-and-widget-state-association)
-- [Caveats and limitations](/library/advanced-features/session-state#caveats-and-limitations)
-
-
-
-
-
-##### Pre-release features
-
-At Streamlit, we like to move quick while keeping things stable. In our latest effort to move even faster without sacrificing stability, we're offering our bold and fearless users two ways to try out Streamlit's bleeding-edge features.
-
-- [Experimental features](/library/advanced-features/prerelease#experimental-features)
-- [Nightly releases](/library/advanced-features/prerelease#nightly-releases)
-
-
-
-
-
-##### Secrets management
-
-This section provides examples of how to use secrets management to store and retrieve sensitive information in your Streamlit app.
-
-- [Develop locally and set up secrets](/library/advanced-features/secrets-management#develop-locally-and-set-up-secrets)
-- [Use secrets in your app](/library/advanced-features/secrets-management#use-secrets-in-your-app)
-- [Error handling](/library/advanced-features/secrets-management#error-handling)
-- [Use secrets on Streamlit Community Cloud](/library/advanced-features/secrets-management#use-secrets-on-streamlit-community-cloud)
-
-
-
-
-
-##### Working with timezones
-
-Working with timezones can be tricky. This section provides a high-level description of how to handle timezones in Streamlit to avoid unexpected behavior.
-
-- [Overview](/library/advanced-features/timezone-handling#working-with-timezones)
-- [How Streamlit handles timezones](/library/advanced-features/timezone-handling#how-streamlit-handles-timezones)
-- [`datetime` instance without a timezone (naive)](/library/advanced-features/timezone-handling#datetime-instance-without-a-timezone-naive)
-- [`datetime` instance with a timezone](/library/advanced-features/timezone-handling#datetime-instance-with-a-timezone)
-
-
-
-
-
-##### Advanced notes on widget behavior
-
-Widgets are magical and often work how you want. But they can have surprising behavior in some situations. This section provides is a high-level, abstract description of widget behavior, including some common edge-cases.
-
-
-
diff --git a/data/library/advanced-features/prerelease-features.md b/data/library/advanced-features/prerelease-features.md
deleted file mode 100644
index 8a0b4d0b3..000000000
--- a/data/library/advanced-features/prerelease-features.md
+++ /dev/null
@@ -1,81 +0,0 @@
----
-title: Pre-release features
-slug: /library/advanced-features/prerelease
----
-
-# Pre-release features
-
-At Streamlit, we like to move quick while keeping things stable. In our latest effort to move even faster without sacrificing stability, we're offering our bold and fearless users two ways to try out Streamlit's bleeding-edge features:
-
-1. [Experimental features](#experimental-features)
-2. [Nightly releases](#nightly-releases)
-
-## Experimental Features
-
-Less stable Streamlit features have one naming convention: `st.experimental_`. This distinction is a prefix we attach to our command names to make sure their status is clear to everyone.
-
-Here's a quick rundown of what you get from each naming convention:
-
-- **st**: this is where our core features like `st.write` and `st.dataframe` live. If we ever make backward-incompatible changes to these, they will take place gradually and with months of announcements and warnings.
-- **experimental**: this is where we'll put all new features that may or may not ever make it into Streamlit core. This gives you a chance to try the next big thing we're cooking up weeks or months before we're ready to stabilize its API. We don't know whether these features have a future, but we want you to have access to everything we're trying, and work with us to figure them out.
-
-Features with the `experimental_` naming convention are things that we're still working on or trying
-to understand. If these features are successful, at some point they'll become part of Streamlit
-core. If unsuccessful, these features are removed without much notice. While in experimental, a feature's API and behaviors may not be stable, and it's possible they could change in ways that aren't backward-compatible.
-
-
-
-Experimental features and their APIs may change or be removed at any time.
-
-
-
-### The lifecycle of an experimental feature
-
-1. A feature is added with the `experimental_` prefix.
-2. The feature is potentially tweaked over time, with possible API/behavior breakages.
-3. If successful, we promote the feature to Streamlit core and remove it from `experimental_`:
- - a\. The feature's API stabilizes and the feature is _cloned_ without the `experimental_` prefix, so it exists as both `st` and `experimental_`. At this point, users will see a warning when using the version of the feature with the `experimental_` prefix -- but the feature will still work.
- - b\. At some point, the code of the `experimental_`-prefixed feature is _removed_, but there will still be a stub of the function prefixed with `experimental_` that shows an error with appropriate instructions.
- - c\. Finally, at a later date the `experimental_` version is removed.
-4. If unsuccessful, the feature is removed without much notice and we leave a stub in `experimental_` that shows an error with instructions.
-
-## Nightly releases
-
-In addition to experimental features, we offer another way to try out Streamlit's newest features: nightly releases.
-
-At the end of each day (at night 🌛), our bots run automated tests against the latest Streamlit code and, if everything looks good, it publishes them as the `streamlit-nightly` package. This means the nightly build includes all our latest features, bug fixes, and other enhancements on the same day they land on our codebase.
-
-**How does this differ from official releases?**
-
-Official Streamlit releases go not only through both automated tests but also rigorous manual testing, while nightly releases only have automated tests. It's important to keep in mind that new features introduced in nightly releases often lack polish. In our official releases, we always make double-sure all new features are ready for prime time.
-
-**How do I use the nightly release?**
-
-All you need to do is install the `streamlit-nightly` package:
-
-```bash
-pip uninstall streamlit
-pip install streamlit-nightly --upgrade
-```
-
-
-
-You should never have both `streamlit` and `streamlit-nightly` installed in the same environment!
-
-
-
-**Why should I use the nightly release?**
-
-Because you can't wait for official releases, and you want to help us find bugs early!
-
-**Why shouldn't I use the nightly release?**
-
-While our automated tests have high coverage, there's still a significant likelihood that there will be some bugs in the nightly code.
-
-**Can I choose which nightly release I want to install?**
-
-If you'd like to use a specific version, you can find the version number in our [Release history](https://pypi.org/project/streamlit-nightly/#history). Specify the desired version using `pip` as usual: `pip install streamlit-nightly==x.yy.zz-123456`.
-
-**Can I compare changes between releases?**
-
-If you'd like to review the changes for a nightly release, you can use the [comparison tool on GitHub](https://github.com/streamlit/streamlit/compare/0.57.3...0.57.4.dev20200412).
diff --git a/data/library/advanced-features/secrets-management.md b/data/library/advanced-features/secrets-management.md
deleted file mode 100644
index 92cca188c..000000000
--- a/data/library/advanced-features/secrets-management.md
+++ /dev/null
@@ -1,114 +0,0 @@
----
-title: Secrets management
-slug: /library/advanced-features/secrets-management
----
-
-# Secrets management
-
-Storing unencrypted secrets in a git repository is a bad practice. For applications that require access to sensitive credentials, the recommended solution is to store those credentials outside the repository - such as using a credentials file not committed to the repository or passing them as environment variables.
-
-Streamlit provides native file-based secrets management to easily store and securely access your secrets in your Streamlit app.
-
-
-
-Existing secrets management tools, such as [dotenv files](https://pypi.org/project/python-dotenv/), [AWS credentials files](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials), [Google Cloud Secret Manager](https://pypi.org/project/google-cloud-secret-manager/), or [Hashicorp Vault](https://www.vaultproject.io/use-cases/secrets-management), will work fine in Streamlit. We just add native secrets management for times when it's useful.
-
-
-
-## How to use secrets management
-
-### Develop locally and set up secrets
-
-Streamlit provides two ways to set up secrets locally using [TOML](https://toml.io/en/latest) format:
-
-1. In a **global secrets file** at `~/.streamlit/secrets.toml` for macOS/Linux or `%userprofile%/.streamlit/secrets.toml` for Windows:
-
- ```toml
- # Everything in this section will be available as an environment variable
- db_username = "Jane"
- db_password = "mypassword"
-
- # You can also add other sections if you like.
- # The contents of sections as shown below will not become environment variables,
- # but they'll be easily accessible from within Streamlit anyway as we show
- # later in this doc.
- [my_other_secrets]
- things_i_like = ["Streamlit", "Python"]
- ```
-
- If you use the global secrets file, you don't have to duplicate secrets across several project-level files if multiple Streamlit apps share the same secrets.
-
-2. In a **per-project secrets file** at `$CWD/.streamlit/secrets.toml`, where `$CWD` is the folder you're running Streamlit from. If both a global secrets file and a per-project secrets file exist, _secrets in the per-project file overwrite those defined in the global file_.
-
-
-
-Add this file to your `.gitignore` so you don't commit your secrets!
-
-
-
-### Use secrets in your app
-
-Access your secrets by querying the `st.secrets` dict, or as environment variables. For example, if you enter the secrets from the section above, the code below shows you how to access them within your Streamlit app.
-
-```python
-import streamlit as st
-
-# Everything is accessible via the st.secrets dict:
-
-st.write("DB username:", st.secrets["db_username"])
-st.write("DB password:", st.secrets["db_password"])
-
-# And the root-level secrets are also accessible as environment variables:
-
-import os
-
-st.write(
- "Has environment variables been set:",
- os.environ["db_username"] == st.secrets["db_username"],
-)
-```
-
-
-
-You can access `st.secrets` via attribute notation (e.g. `st.secrets.key`), in addition to key notation (e.g. `st.secrets["key"]`) — like [st.session_state](/library/api-reference/session-state).
-
-
-
-You can even compactly use TOML sections to pass multiple secrets as a single attribute. Consider the following secrets:
-
-```toml
-[db_credentials]
-username = "my_username"
-password = "my_password"
-```
-
-Rather than passing each secret as attributes in a function, you can more compactly pass the section to achieve the same result. See the notional code below, which uses the secrets above:
-
-```python
-# Verbose version
-my_db.connect(username=st.secrets.db_credentials.username, password=st.secrets.db_credentials.password)
-
-# Far more compact version!
-my_db.connect(**st.secrets.db_credentials)
-```
-
-### Error handling
-
-Here are some common errors you might encounter when using secrets management.
-
-- If a `.streamlit/secrets.toml` is created _while_ the app is running, the server needs to be restarted for changes to be reflected in the app.
-- If you try accessing a secret, but no `secrets.toml` file exists, Streamlit will raise a `FileNotFoundError` exception:
-
-- If you try accessing a secret that doesn't exist, Streamlit will raise a `KeyError` exception:
-
- ```python
- import streamlit as st
-
- st.write(st.secrets["nonexistent_key"])
- ```
-
-
-
-### Use secrets on Streamlit Community Cloud
-
-When you deploy your app to [Streamlit Community Cloud](https://streamlit.io/cloud), you can use the same secrets management workflow as you would locally. However, you'll need to also set up your secrets in the Community Cloud Secrets Management console. Learn how to do so via the Cloud-specific [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management) documentation.
diff --git a/data/library/advanced-features/session-state.md b/data/library/advanced-features/session-state.md
deleted file mode 100644
index 78441926b..000000000
--- a/data/library/advanced-features/session-state.md
+++ /dev/null
@@ -1,307 +0,0 @@
----
-title: Add statefulness to apps
-slug: /library/advanced-features/session-state
----
-
-# Add statefulness to apps
-
-## What is State?
-
-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.
-
-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. Session state also persists across apps inside a [multipage app](/library/get-started/multipage-apps).
-
-In this guide, we will illustrate the usage of **Session State** and **Callbacks** as we build a stateful Counter app.
-
-For details on the Session State and Callbacks API, please refer to our [Session State API Reference Guide](/library/api-reference/session-state).
-
-Also, check out this Session State basics tutorial video by Streamlit Developer Advocate Dr. Marisa Smith to get started:
-
-
-
-## Build a Counter
-
-Let's call our script `counter.py`. It initializes a `count` variable and has a button to increment the value stored in the `count` variable:
-
-```python
-import streamlit as st
-
-st.title('Counter Example')
-count = 0
-
-increment = st.button('Increment')
-if increment:
- count += 1
-
-st.write('Count = ', count)
-```
-
-No matter how many times we press the **_Increment_** button in the above app, the `count` remains at 1. Let's understand why:
-
-- Each time we press the **_Increment_** button, Streamlit reruns `counter.py` from top to bottom, and with every run, `count` gets initialized to `0` .
-- Pressing **_Increment_** subsequently adds 1 to 0, thus `count=1` no matter how many times we press **_Increment_**.
-
-As we'll see later, we can avoid this issue by storing `count` as a Session State variable. By doing so, we're indicating to Streamlit that it should maintain the value stored inside a Session State variable across app reruns.
-
-Let's learn more about the API to use Session State.
-
-### Initialization
-
-The Session State API follows a field-based API, which is very similar to Python dictionaries:
-
-```python
-import streamlit as st
-
-# Check if 'key' already exists in session_state
-# If not, then initialize it
-if 'key' not in st.session_state:
- st.session_state['key'] = 'value'
-
-# Session State also supports the attribute based syntax
-if 'key' not in st.session_state:
- st.session_state.key = 'value'
-```
-
-### Reads and updates
-
-Read the value of an item in Session State by passing the item to `st.write` :
-
-```python
-import streamlit as st
-
-if 'key' not in st.session_state:
- st.session_state['key'] = 'value'
-
-# Reads
-st.write(st.session_state.key)
-
-# Outputs: value
-```
-
-Update an item in Session State by assigning it a value:
-
-```python
-import streamlit as st
-
-if 'key' not in st.session_state:
- st.session_state['key'] = 'value'
-
-# Updates
-st.session_state.key = 'value2' # Attribute API
-st.session_state['key'] = 'value2' # Dictionary like API
-```
-
-Streamlit throws an exception if an uninitialized variable is accessed:
-
-```python
-import streamlit as st
-
-st.write(st.session_state['value'])
-
-# Throws an exception!
-```
-
-
-
-Let's now take a look at a few examples that illustrate how to add Session State to our Counter app.
-
-### Example 1: Add Session State
-
-Now that we've got a hang of the Session State API, let's update our Counter app to use Session State:
-
-```python
-import streamlit as st
-
-st.title('Counter Example')
-if 'count' not in st.session_state:
- st.session_state.count = 0
-
-increment = st.button('Increment')
-if increment:
- st.session_state.count += 1
-
-st.write('Count = ', st.session_state.count)
-```
-
-As you can see in the above example, pressing the **_Increment_** button updates the `count` each time.
-
-### Example 2: Session State and Callbacks
-
-Now that we've built a basic Counter app using Session State, let's move on to something a little more complex. The next example uses Callbacks with Session State.
-
-**Callbacks**: A callback is a Python function which gets called when an input widget changes. Callbacks can be used with widgets using the parameters `on_change` (or `on_click`), `args`, and `kwargs`. The full Callbacks API can be found in our [Session State API Reference Guide](/library/api-reference/session-state#use-callbacks-to-update-session-state).
-
-```python
-import streamlit as st
-
-st.title('Counter Example using Callbacks')
-if 'count' not in st.session_state:
- st.session_state.count = 0
-
-def increment_counter():
- st.session_state.count += 1
-
-st.button('Increment', on_click=increment_counter)
-
-st.write('Count = ', st.session_state.count)
-```
-
-Now, pressing the **_Increment_** button updates the count each time by calling the `increment_counter()` function.
-
-### Example 3: Use args and kwargs in Callbacks
-
-Callbacks also support passing arguments using the `args` parameter in a widget:
-
-```python
-import streamlit as st
-
-st.title('Counter Example using Callbacks with args')
-if 'count' not in st.session_state:
- st.session_state.count = 0
-
-increment_value = st.number_input('Enter a value', value=0, step=1)
-
-def increment_counter(increment_value):
- st.session_state.count += increment_value
-
-increment = st.button('Increment', on_click=increment_counter,
- args=(increment_value, ))
-
-st.write('Count = ', st.session_state.count)
-```
-
-Additionally, we can also use the `kwargs` parameter in a widget to pass named arguments to the callback function as shown below:
-
-```python
-import streamlit as st
-
-st.title('Counter Example using Callbacks with kwargs')
-if 'count' not in st.session_state:
- st.session_state.count = 0
-
-def increment_counter(increment_value=0):
- st.session_state.count += increment_value
-
-def decrement_counter(decrement_value=0):
- st.session_state.count -= decrement_value
-
-st.button('Increment', on_click=increment_counter,
- kwargs=dict(increment_value=5))
-
-st.button('Decrement', on_click=decrement_counter,
- kwargs=dict(decrement_value=1))
-
-st.write('Count = ', st.session_state.count)
-```
-
-### Example 4: Forms and Callbacks
-
-Say we now want to not only increment the `count`, but also store when it was last updated. We illustrate doing this using Callbacks and `st.form`:
-
-```python
-import streamlit as st
-import datetime
-
-st.title('Counter Example')
-if 'count' not in st.session_state:
- st.session_state.count = 0
- st.session_state.last_updated = datetime.time(0,0)
-
-def update_counter():
- st.session_state.count += st.session_state.increment_value
- st.session_state.last_updated = st.session_state.update_time
-
-with st.form(key='my_form'):
- st.time_input(label='Enter the time', value=datetime.datetime.now().time(), key='update_time')
- st.number_input('Enter a value', value=0, step=1, key='increment_value')
- submit = st.form_submit_button(label='Update', on_click=update_counter)
-
-st.write('Current Count = ', st.session_state.count)
-st.write('Last Updated = ', st.session_state.last_updated)
-```
-
-## Advanced concepts
-
-### Session State and Widget State association
-
-Session State provides the functionality to store variables across reruns. Widget state (i.e. the value of a widget) is also stored in a session.
-
-For simplicity, we have _unified_ this information in one place. i.e. the Session State. This convenience feature makes it super easy to read or write to the widget's state anywhere in the app's code. Session State variables mirror the widget value using the `key` argument.
-
-We illustrate this with the following example. Let's say we have an app with a slider to represent temperature in Celsius. We can **set** and **get** the value of the temperature widget by using the Session State API, as follows:
-
-```python
-import streamlit as st
-
-if "celsius" not in st.session_state:
- # set the initial default value of the slider widget
- st.session_state.celsius = 50.0
-
-st.slider(
- "Temperature in Celsius",
- min_value=-100.0,
- max_value=100.0,
- key="celsius"
-)
-
-# This will get the value of the slider widget
-st.write(st.session_state.celsius)
-```
-
-There is a limitation to setting widget values using the Session State API.
-
-
-
-Streamlit **does not allow** setting widget values via the Session State API for `st.button` and `st.file_uploader`.
-
-
-
-The following example will raise a `StreamlitAPIException` on trying to set the state of `st.button` via the Session State API:
-
-```python
-import streamlit as st
-
-if 'my_button' not in st.session_state:
- st.session_state.my_button = True
- # Streamlit will raise an Exception on trying to set the state of button
-
-st.button('Submit', key='my_button')
-```
-
-
-
-### Serializable Session State
-
-Serialization refers to the process of converting an object or data structure into a format that can be persisted and shared, and allowing you to recover the data’s original structure. Python’s built-in [pickle](https://docs.python.org/3/library/pickle.html) module serializes Python objects to a byte stream ("pickling") and deserializes the stream into an object ("unpickling").
-
-By default, Streamlit’s [Session State](/library/advanced-features/session-state) allows you to persist any Python object for the duration of the session, irrespective of the object’s pickle-serializability. This property lets you store Python primitives such as integers, floating-point numbers, complex numbers and booleans, dataframes, and even [lambdas](https://docs.python.org/3/reference/expressions.html#lambda) returned by functions. However, some execution environments may require serializing all data in Session State, so it may be useful to detect incompatibility during development, or when the execution environment will stop supporting it in the future.
-
-To that end, Streamlit provides a `runner.enforceSerializableSessionState` [configuration option](https://docs.streamlit.io/library/advanced-features/configuration) that, when set to `true`, only allows pickle-serializable objects in Session State. To enable the option, either create a global or project config file with the following or use it as a command-line flag:
-
-```toml
-# .streamlit/config.toml
-[runner]
-enforceSerializableSessionState = true
-```
-
-By "_pickle-serializable_", we mean calling `pickle.dumps(obj)` should not raise a [`PicklingError`](https://docs.python.org/3/library/pickle.html#pickle.PicklingError) exception. When the config option is enabled, adding unserializable data to session state should result in an exception. E.g.,
-
-```python
-import streamlit as st
-
-def unserializable_data():
- return lambda x: x
-
-#👇 results in an exception when enforceSerializableSessionState is on
-st.session_state.unserializable = unserializable_data()
-```
-
-
-
-### Caveats and limitations
-
-Here are some limitations to keep in mind when using Session State:
-
-- Session State exists for as long as the tab is open and connected to the Streamlit server. As soon as you close the tab, everything stored in Session State is lost.
-- Session State is not persisted. If the Streamlit server crashes, then everything stored in Session State gets wiped
-- For caveats and limitations with the Session State API, please see the [API limitations](/library/api-reference/session-state#caveats-and-limitations).
diff --git a/data/library/advanced-features/static-file-serving.md b/data/library/advanced-features/static-file-serving.md
deleted file mode 100644
index 744a4886b..000000000
--- a/data/library/advanced-features/static-file-serving.md
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: Static file serving
-slug: /library/advanced-features/static-file-serving
----
-
-# Static file serving
-
-Streamlit apps can host and serve small, static media files to support media embedding use cases that
-won't work with the normal [media elements](https://docs.streamlit.io/library/api-reference/media).
-
-To enable this feature, set `enableStaticServing = true` under `[server]` in your config file,
-or environment variable `STREAMLIT_SERVER_ENABLE_STATIC_SERVING=true`.
-
-Media stored in the folder `./static/` relative to the running app file is served at path
-`app/static/[filename]`, such as `http://localhost:8501/app/static/cat.png`.
-
-## Details on usage
-
-- Files with the following extensions will be served normally: `".jpg", ".jpeg", ".png", ".gif"`. Any other
- file will be sent with header `Content-Type:text/plain` which will cause browsers to render in plain text.
- This is included for security - other file types that need to render should be hosted outside the app.
-- Streamlit also sets `X-Content-Type-Options:nosniff` for all files rendered from the static directory.
-- For apps running on Streamlit Community Cloud:
- - Files available in the Github repo will always be served. Any files generated while the app is running,
- such as based on user interaction (file upload, etc), are not guaranteed to persist across user sessions.
- - Apps which store and serve many files, or large files, may run into resource limits and be shut down.
-
-## Example usage
-
-- Put an image `cat.png` in the folder `./static/`
-- Add `enableStaticServing = true` under `[server]` in your `.streamlit/config.toml`
-- Any media in the `./static/` folder is served at the relative URL like `app/static/cat.png`
-
-```toml
-# .streamlit/config.toml
-
-[server]
-enableStaticServing = true
-```
-
-```python
-# app.py
-import streamlit as st
-
-with st.echo():
- st.title("CAT")
-
- st.markdown("[](https://streamlit.io)")
-
-```
-
-Additional resources:
-
--
--
-
-
diff --git a/data/library/advanced-features/theming.md b/data/library/advanced-features/theming.md
deleted file mode 100644
index 593b7514a..000000000
--- a/data/library/advanced-features/theming.md
+++ /dev/null
@@ -1,109 +0,0 @@
----
-title: Theming
-slug: /library/advanced-features/theming
----
-
-# Theming
-
-In this guide, we provide examples of how Streamlit page elements are affected
-by the various theme config options. For a more high-level overview of
-Streamlit themes, see the Themes section of the
-[main concepts documentation](/library/get-started/main-concepts#themes).
-
-Streamlit themes are defined using regular config options: a theme can be set
-via command line flag when starting your app using `streamlit run` or by
-defining it in the `[theme]` section of a `.streamlit/config.toml` file. For
-more information on setting config options, please refer to the
-[Streamlit configuration documentation](/library/advanced-features/configuration#set-configuration-options).
-
-The following config options show the default Streamlit Light theme recreated
-in the `[theme]` section of a `.streamlit/config.toml` file.
-
-```toml
-[theme]
-primaryColor="#F63366"
-backgroundColor="#FFFFFF"
-secondaryBackgroundColor="#F0F2F6"
-textColor="#262730"
-font="sans serif"
-```
-
-Let's go through each of these options, providing screenshots to demonstrate
-what parts of a Streamlit app they affect where needed.
-
-## primaryColor
-
-`primaryColor` defines the accent color most often used throughout a Streamlit
-app. A few examples of Streamlit widgets that use `primaryColor` include
-`st.checkbox`, `st.slider`, and `st.text_input` (when focused).
-
-
-
-
-
-Any CSS color can be used as the value for primaryColor and the other color
-options below. This means that theme colors can be specified in hex or with
-browser-supported color names like "green", "yellow", and
-"chartreuse". They can even be defined in the RGB and HSL formats!
-
-
-
-## backgroundColor
-
-Defines the background color used in the main content area of your app.
-
-## secondaryBackgroundColor
-
-This color is used where a second background color is needed for added
-contrast. Most notably, it is the sidebar's background color. It is also used
-as the background color for most interactive widgets.
-
-
-
-## textColor
-
-This option controls the text color for most of your Streamlit app.
-
-## font
-
-Selects the font used in your Streamlit app. Valid values are `"sans serif"`,
-`"serif"`, and `"monospace"`. This option defaults to `"sans serif"` if unset
-or invalid.
-
-Note that code blocks are always rendered using the monospace font regardless of
-the font selected here.
-
-## base
-
-An easy way to define custom themes that make small changes to one of the
-preset Streamlit themes is to use the `base` option. Using `base`, the
-Streamlit Light theme can be recreated as a custom theme by writing the
-following:
-
-```toml
-[theme]
-base="light"
-```
-
-The `base` option allows you to specify a preset Streamlit theme that your
-custom theme inherits from. Any theme config options not defined in your theme
-settings have their values set to those of the base theme. Valid values for
-`base` are `"light"` and `"dark"`.
-
-For example, the following theme config defines a custom theme nearly identical
-to the Streamlit Dark theme, but with a new `primaryColor`.
-
-```toml
-[theme]
-base="dark"
-primaryColor="purple"
-```
-
-If `base` itself is omitted, it defaults to `"light"`, so you can define a
-custom theme that changes the font of the Streamlit Light theme to serif with
-the following config
-
-```toml
-[theme]
-font="serif"
-```
diff --git a/data/library/advanced-features/timezone-handling.md b/data/library/advanced-features/timezone-handling.md
deleted file mode 100644
index 5ac5f777a..000000000
--- a/data/library/advanced-features/timezone-handling.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: Working with timezones
-slug: /library/advanced-features/timezone-handling
----
-
-# Working with timezones
-
-In general, working with timezones can be tricky. Your Streamlit app users are not necessarily in the same timezone as the server running your app. It is especially true of public apps, where anyone in the world (in any timezone) can access your app. As such, it is crucial to understand how Streamlit handles timezones, so you can avoid unexpected behavior when displaying `datetime` information.
-
-## How Streamlit handles timezones
-
-Streamlit always shows `datetime` information on the frontend with the same information as its corresponding `datetime` instance in the backend. I.e., date or time information does not automatically adjust to the users' timezone. We distinguish between the following two cases:
-
-### **`datetime` instance without a timezone (naive)**
-
-When you provide a `datetime` instance _without specifying a timezone_, the frontend shows the `datetime` instance without timezone information. For example (this also applies to other widgets like [`st.dataframe`](/library/api-reference/data/st.dataframe)):
-
-```python
-import streamlit as st
-from datetime import datetime
-
-st.write(datetime(2020, 1, 10, 10, 30))
-# Outputs: 2020-01-10 10:30:00
-```
-
-Users of the above app always see the output as `2020-01-10 10:30:00`.
-
-### **`datetime` instance with a timezone**
-
-When you provide a `datetime` instance _and specify a timezone_, the frontend shows the `datetime` instance in that same timezone. For example (this also applies to other widgets like [`st.dataframe`](/library/api-reference/data/st.dataframe)):
-
-```python
-import streamlit as st
-from datetime import datetime
-import pytz
-
-st.write(datetime(2020, 1, 10, 10, 30, tzinfo=pytz.timezone("EST")))
-# Outputs: 2020-01-10 10:30:00-05:00
-```
-
-Users of the above app always see the output as `2020-01-10 10:30:00-05:00`.
-
-In both cases, neither the date nor time information automatically adjusts to the users' timezone on the frontend. What users see is identical to the corresponding `datetime` instance in the backend. It is currently not possible to automatically adjust the date or time information to the timezone of the users viewing the app.
-
-
-
-The legacy version of the `st.dataframe` has issues with timezones. We do not plan to roll out additional fixes or enhancements for the legacy dataframe. If you need stable timezone support, please consider switching to the arrow serialization by changing the [config setting](/library/advanced-features/configuration#set-configuration-options), _config.dataFrameSerialization = "arrow"_.
-
-
diff --git a/data/library/api/api-reference.md b/data/library/api/api-reference.md
deleted file mode 100644
index 13a9e382b..000000000
--- a/data/library/api/api-reference.md
+++ /dev/null
@@ -1,2120 +0,0 @@
----
-title: API Reference
-slug: /library/api-reference
-next: caching
-previous: index.md
----
-
-# API reference
-
-Streamlit makes it easy for you to visualize, mutate, and share data. The API
-reference is organized by activity type, like displaying data or optimizing
-performance. Each section includes methods associated with the activity type,
-including examples.
-
-Browse our API below and click to learn more about any of our available commands! 🎈
-
-## Display almost anything
-
-
-
-
-#### st.write
-
-Write arguments to the app.
-
-```python
-st.write("Hello **world**!")
-st.write(my_data_frame)
-st.write(my_mpl_figure)
-```
-
-
-
-
-#### Magic
-
-Any time Streamlit sees either a variable or literal value on its own line, it automatically writes that to your app using `st.write`
-
-```python
-"Hello **world**!"
-my_data_frame
-my_mpl_figure
-```
-
-
-
-
-## Text elements
-
-
-
-
-
-
-#### Markdown
-
-Display string formatted as Markdown.
-
-```python
-st.markdown("Hello **world**!")
-```
-
-
-
-
-
-
-#### Title
-
-Display text in title formatting.
-
-```python
-st.title("The app title")
-```
-
-
-
-
-
-
-#### Header
-
-Display text in header formatting.
-
-```python
-st.header("This is a header")
-```
-
-
-
-
-
-
-#### Subheader
-
-Display text in subheader formatting.
-
-```python
-st.subheader("This is a subheader")
-```
-
-
-
-
-
-
-#### Caption
-
-Display text in small font.
-
-```python
-st.caption("This is written small caption text")
-```
-
-
-
-
-
-
-#### Code block
-
-Display a code block with optional syntax highlighting.
-
-```python
-st.code("a = 1234")
-```
-
-
-
-
-
-
-#### Preformatted text
-
-Write fixed-width and preformatted text.
-
-```python
-st.text("Hello world")
-```
-
-
-
-
-
-
-#### LaTeX
-
-Display mathematical expressions formatted as LaTeX.
-
-```python
-st.latex("\int a x^2 \,dx")
-```
-
-
-
-
-
-
-#### Divider
-
-Display a horizontal rule.
-
-```python
-st.divider()
-```
-
-
-
-
-
-
-
-
-
-#### Annotated text
-
-Display annotated text in Streamlit apps. Created by [@tvst](https://github.com/tvst).
-
-```python
-annotated_text("This ", ("is", "verb"), " some ", ("annotated", "adj"), ("text", "noun"), " for those of ", ("you", "pronoun"), " who ", ("like", "verb"), " this sort of ", ("thing", "noun"), ".")
-```
-
-
-
-
-
-
-
-#### Drawable Canvas
-
-Provides a sketching canvas using [Fabric.js](http://fabricjs.com/). Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-st_canvas(fill_color="rgba(255, 165, 0, 0.3)", stroke_width=stroke_width, stroke_color=stroke_color, background_color=bg_color, background_image=Image.open(bg_image) if bg_image else None, update_streamlit=realtime_update, height=150, drawing_mode=drawing_mode, point_display_radius=point_display_radius if drawing_mode == 'point' else 0, key="canvas",)
-```
-
-
-
-
-
-
-
-#### Tags
-
-Add tags to your Streamlit apps. Created by [@gagan3012](https://github.com/gagan3012).
-
-```python
-st_tags(label='# Enter Keywords:', text='Press enter to add more', value=['Zero', 'One', 'Two'], suggestions=['five', 'six', 'seven', 'eight', 'nine', 'three', 'eleven', 'ten', 'four'], maxtags = 4, key='1')
-```
-
-
-
-
-
-
-
-#### NLU
-
-Apply text mining on a dataframe. Created by [@JohnSnowLabs](https://github.com/JohnSnowLabs/).
-
-```python
-nlu.load('sentiment').predict('I love NLU! <3')
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-mention(label="An awesome Streamlit App", icon="streamlit", url="https://extras.streamlit.app",)
-```
-
-
-
-
-## Data elements
-
-
-
-
-
-#### Dataframes
-
-Display a dataframe as an interactive table.
-
-```python
-st.dataframe(my_data_frame)
-```
-
-
-
-
-
-
-#### Data editor
-
-Display a data editor widget.
-
-```python
-edited = st.data_editor(df, num_rows="dynamic")
-```
-
-
-
-
-
-
-#### Column configuration
-
-Configure the display and editing behavior of dataframes and data editors.
-
-```python
-st.column_config.NumberColumn("Price (in USD)", min_value=0, format="$%d")
-```
-
-
-
-
-
-
-#### Static tables
-
-Display a static table.
-
-```python
-st.table(my_data_frame)
-```
-
-
-
-
-
-#### Metrics
-
-Display a metric in big bold font, with an optional indicator of how the metric changed.
-
-```python
-st.metric("My metric", 42, 2)
-```
-
-
-
-
-
-#### Dicts and JSON
-
-Display object or string as a pretty-printed JSON string.
-
-```python
-st.json(my_dict)
-```
-
-
-
-
-
-
-
-
-
-
-#### Streamlit Aggrid
-
-Implementation of Ag-Grid component for Streamlit. Created by [@PablocFonseca](https://github.com/PablocFonseca).
-
-```python
-df = pd.DataFrame({'col1': [1, 2, 3], 'col2': [4, 5, 6]})
-grid_return = AgGrid(df, editable=True)
-
-new_df = grid_return['data']
-```
-
-
-
-
-
-
-
-#### Streamlit Folium
-
-Streamlit Component for rendering Folium maps. Created by [@randyzwitch](https://github.com/randyzwitch).
-
-```python
-m = folium.Map(location=[39.949610, -75.150282], zoom_start=16)
-folium.Marker([39.949610, -75.150282], popup="Liberty Bell", tooltip="Liberty Bell").add_to(m)
-
-st_data = st_folium(m, width=725)
-```
-
-
-
-
-
-
-
-#### Pandas Profiling
-
-Pandas profiling component for Streamlit. Created by [@okld](https://github.com/okld/).
-
-```python
-df = pd.read_csv("https://storage.googleapis.com/tf-datasets/titanic/train.csv")
-pr = df.profile_report()
-
-st_profile_report(pr)
-```
-
-
-
-
-
-
-
-#### Image Coordinates
-
-Get the coordinates of clicks on an image. Created by [@blackary](https://github.com/blackary/).
-
-```python
-from streamlit_image_coordinates import streamlit_image_coordinates
-value = streamlit_image_coordinates("https://placekitten.com/200/300")
-
-st.write(value)
-```
-
-
-
-
-
-
-
-#### Plotly Events
-
-Make Plotly charts interactive!. Created by [@null-jones](https://github.com/null-jones/).
-
-```python
-from streamlit_plotly_events import plotly_events
-fig = px.line(x=[1], y=[1])
-
-selected_points = plotly_events(fig)
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-from streamlit_extras.metric_cards import style_metric_cards
-col3.metric(label="No Change", value=5000, delta=0)
-
-style_metric_cards()
-```
-
-
-
-
-
-## Chart elements
-
-
-
-
-
-#### Simple line charts
-
-Display a line chart.
-
-```python
-st.line_chart(my_data_frame)
-```
-
-
-
-
-
-#### Simple area charts
-
-Display an area chart.
-
-```python
-st.area_chart(my_data_frame)
-```
-
-
-
-
-
-#### Simple bar charts
-
-Display a bar chart.
-
-```python
-st.bar_chart(my_data_frame)
-```
-
-
-
-
-
-#### Scatterplots on maps
-
-Display a map with points on it.
-
-```python
-st.map(my_data_frame)
-```
-
-
-
-
-
-#### Matplotlib
-
-Display a matplotlib.pyplot figure.
-
-```python
-st.pyplot(my_mpl_figure)
-```
-
-
-
-
-
-#### Altair
-
-Display a chart using the Altair library.
-
-```python
-st.altair_chart(my_altair_chart)
-```
-
-
-
-
-
-#### Vega-Lite
-
-Display a chart using the Vega-Lite library.
-
-```python
-st.vega_lite_chart(my_vega_lite_chart)
-```
-
-
-
-
-
-#### Plotly
-
-Display an interactive Plotly chart.
-
-```python
-st.plotly_chart(my_plotly_chart)
-```
-
-
-
-
-
-#### Bokeh
-
-Display an interactive Bokeh chart.
-
-```python
-st.bokeh_chart(my_bokeh_chart)
-```
-
-
-
-
-
-#### PyDeck
-
-Display a chart using the PyDeck library.
-
-```python
-st.pydeck_chart(my_pydeck_chart)
-```
-
-
-
-
-
-#### GraphViz
-
-Display a graph using the dagre-d3 library.
-
-```python
-st.graphviz_chart(my_graphviz_spec)
-```
-
-
-
-
-
-
-
-
-
-
-#### Plost
-
-A deceptively simple plotting library for Streamlit. Created by [@tvst](https://github.com/tvst).
-
-```python
-import plost
-plost.line_chart(my_dataframe, x='time', y='stock_value', color='stock_name',)
-```
-
-
-
-
-
-
-
-#### HiPlot
-
-High dimensional Interactive Plotting. Created by [@facebookresearch](https://github.com/facebookresearch).
-
-```python
-data = [{'dropout':0.1, 'lr': 0.001, 'loss': 10.0, 'optimizer': 'SGD'}, {'dropout':0.15, 'lr': 0.01, 'loss': 3.5, 'optimizer': 'Adam'}, {'dropout':0.3, 'lr': 0.1, 'loss': 4.5, 'optimizer': 'Adam'}]
-hip.Experiment.from_iterable(data).display()
-```
-
-
-
-
-
-
-
-#### ECharts
-
-High dimensional Interactive Plotting. Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-from streamlit_echarts import st_echarts
-st_echarts(options=options)
-```
-
-
-
-
-
-
-
-#### Streamlit Folium
-
-Streamlit Component for rendering Folium maps. Created by [@randyzwitch](https://github.com/randyzwitch).
-
-```python
-m = folium.Map(location=[39.949610, -75.150282], zoom_start=16)
-st_data = st_folium(m, width=725)
-```
-
-
-
-
-
-
-
-#### Spacy-Streamlit
-
-spaCy building blocks and visualizers for Streamlit apps. Created by [@explosion](https://github.com/explosion).
-
-```python
-models = ["en_core_web_sm", "en_core_web_md"]
-spacy_streamlit.visualize(models, "Sundar Pichai is the CEO of Google.")
-```
-
-
-
-
-
-
-
-#### Streamlit Agraph
-
-A Streamlit Graph Vis, based on [react-grah-vis](https://github.com/crubier/react-graph-vis). Created by [@ChrisDelClea](https://github.com/ChrisDelClea).
-
-```python
-from streamlit_agraph import agraph, Node, Edge, Config
-agraph(nodes=nodes, edges=edges, config=config)
-```
-
-
-
-
-
-
-
-#### Streamlit Lottie
-
-Integrate [Lottie](https://lottiefiles.com/) animations inside your Streamlit app. Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-lottie_hello = load_lottieurl("https://assets5.lottiefiles.com/packages/lf20_V9t630.json")
-st_lottie(lottie_hello, key="hello")
-```
-
-
-
-
-
-
-
-#### Plotly Events
-
-Make Plotly charts interactive!. Created by [@null-jones](https://github.com/null-jones/).
-
-```python
-fig = px.line(x=[1], y=[1])
-selected_points = plotly_events(fig)
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-chart += get_annotations_chart(annotations=[("Mar 01, 2008", "Pretty good day for GOOG"), ("Dec 01, 2007", "Something's going wrong for GOOG & AAPL"), ("Nov 01, 2008", "Market starts again thanks to..."), ("Dec 01, 2009", "Small crash for GOOG after..."),],)
-st.altair_chart(chart, use_container_width=True)
-```
-
-
-
-
-
-## Input widgets
-
-
-
-
-
-
-#### Button
-
-Display a button widget.
-
-```python
-clicked = st.button("Click me")
-```
-
-
-
-
-
-
-#### Data editor
-
-Display a data editor widget.
-
-```python
-edited = st.experimental_data_editor(df, num_rows="dynamic")
-```
-
-
-
-
-
-
-#### Download button
-
-Display a download button widget.
-
-```python
-st.download_button("Download file", file)
-```
-
-
-
-
-
-
-#### Checkbox
-
-Display a checkbox widget.
-
-```python
-selected = st.checkbox("I agree")
-```
-
-
-
-
-
-
-#### Radio
-
-Display a radio button widget.
-
-```python
-choice = st.radio("Pick one", ["cats", "dogs"])
-```
-
-
-
-
-
-
-#### Selectbox
-
-Display a select widget.
-
-```python
-choice = st.selectbox("Pick one", ["cats", "dogs"])
-```
-
-
-
-
-
-
-#### Multiselect
-
-Display a multiselect widget. The multiselect widget starts as empty.
-
-```python
-choices = st.multiselect("Buy", ["milk", "apples", "potatoes"])
-```
-
-
-
-
-
-
-#### Slider
-
-Display a slider widget.
-
-```python
-number = st.slider("Pick a number", 0, 100)
-```
-
-
-
-
-
-
-#### Select-slider
-
-Display a slider widget to select items from a list.
-
-```python
-size = st.select_slider("Pick a size", ["S", "M", "L"])
-```
-
-
-
-
-
-
-#### Text input
-
-Display a single-line text input widget.
-
-```python
-name = st.text_input("First name")
-```
-
-
-
-
-
-
-#### Number input
-
-Display a numeric input widget.
-
-```python
-choice = st.number_input("Pick a number", 0, 10)
-```
-
-
-
-
-
-
-#### Text-area
-
-Display a multi-line text input widget.
-
-```python
-text = st.text_area("Text to translate")
-```
-
-
-
-
-
-
-#### Date input
-
-Display a date input widget.
-
-```python
-date = st.date_input("Your birthday")
-```
-
-
-
-
-
-
-#### Time input
-
-Display a time input widget.
-
-```python
-time = st.time_input("Meeting time")
-```
-
-
-
-
-
-
-#### File Uploader
-
-Display a file uploader widget.
-
-```python
-data = st.file_uploader("Upload a CSV")
-```
-
-
-
-
-
-
-#### Camera input
-
-Display a widget that allows users to upload images directly from a camera.
-
-```python
-image = st.camera_input("Take a picture")
-```
-
-
-
-
-
-
-#### Color picker
-
-Display a color picker widget.
-
-```python
-color = st.color_picker("Pick a color")
-```
-
-
-
-
-
-
-
-
-
-
-#### Streamlit Elements
-
-Create a draggable and resizable dashboard in Streamlit. Created by [@okls](https://github.com/okls).
-
-```python
-from streamlit_elements import elements, mui, html
-
-with elements("new_element"):
- mui.Typography("Hello world")
-```
-
-
-
-
-
-
-
-#### Tags
-
-Add tags to your Streamlit apps. Created by [@gagan3012](https://github.com/gagan3012).
-
-```python
-from streamlit_tags import st_tags
-
-st_tags(label='# Enter Keywords:', text='Press enter to add more', value=['Zero', 'One', 'Two'],
-suggestions=['five', 'six', 'seven', 'eight', 'nine', 'three', 'eleven', 'ten', 'four'], maxtags = 4, key='1')
-```
-
-
-
-
-
-
-
-#### Stqdm
-
-The simplest way to handle a progress bar in streamlit app. Created by [@Wirg](https://github.com/Wirg).
-
-```python
-from stqdm import stqdm
-
-for _ in stqdm(range(50)):
- sleep(0.5)
-```
-
-
-
-
-
-
-
-#### Timeline
-
-Display a Timeline in Streamlit apps using [TimelineJS](https://timeline.knightlab.com/). Created by [@innerdoc](https://github.com/innerdoc).
-
-```python
-from streamlit_timeline import timeline
-
-with open('example.json', "r") as f:
- timeline(f.read(), height=800)
-```
-
-
-
-
-
-
-
-#### Camera input live
-
-Alternative for st.camera_input which returns the webcam images live. Created by [@blackary](https://github.com/blackary).
-
-```python
-from camera_input_live import camera_input_live
-
-image = camera_input_live()
-st.image(value)
-```
-
-
-
-
-
-
-
-#### Streamlit Ace
-
-Ace editor component for Streamlit. Created by [@okld](https://github.com/okld).
-
-```python
-from streamlit_ace import st_ace
-
-content = st_ace()
-content
-```
-
-
-
-
-
-
-
-#### Streamlit Chat
-
-Streamlit Component for a Chatbot UI. Created by [@AI-Yash](https://github.com/AI-Yash).
-
-```python
-from streamlit_chat import message
-
-message("My message")
-message("Hello bot!", is_user=True) # align's the message to the right
-```
-
-
-
-
-
-
-
-#### Streamlit Option Menu
-
-Select a single item from a list of options in a menu. Created by [@victoryhb](https://github.com/victoryhb).
-
-```python
-from streamlit_option_menu import option_menu
-
-option_menu("Main Menu", ["Home", 'Settings'],
- icons=['house', 'gear'], menu_icon="cast", default_index=1)
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-from streamlit_extras.stoggle import stoggle
-
-stoggle(
- "Click me!", """🥷 Surprise! Here's some additional content""",)
-```
-
-
-
-
-
-## Media elements
-
-
-
-
-
-
-#### Image
-
-Display an image or list of images.
-
-```python
-st.image(numpy_array)
-st.image(image_bytes)
-st.image(file)
-st.image("https://example.com/myimage.jpg")
-```
-
-
-
-
-
-
-#### Audio
-
-Display an audio player.
-
-```python
-st.audio(numpy_array)
-st.audio(audio_bytes)
-st.audio(file)
-st.audio("https://example.com/myaudio.mp3", format="audio/mp3")
-```
-
-
-
-
-
-
-#### Video
-
-Display a video player.
-
-```python
-st.video(numpy_array)
-st.video(video_bytes)
-st.video(file)
-st.video("https://example.com/myvideo.mp4", format="video/mp4")
-```
-
-
-
-
-
-
-
-
-
-
-#### Streamlit Webrtc
-
-Handling and transmitting real-time video/audio streams with Streamlit. Created by [@whitphx](https://github.com/whitphx).
-
-```python
-from streamlit_webrtc import webrtc_streamer
-
-webrtc_streamer(key="sample")
-```
-
-
-
-
-
-
-
-#### Drawable Canvas
-
-Provides a sketching canvas using [Fabric.js](http://fabricjs.com/). Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-from streamlit_drawable_canvas import st_canvas
-
-st_canvas(fill_color="rgba(255, 165, 0, 0.3)", stroke_width=stroke_width, stroke_color=stroke_color, background_color=bg_color, background_image=Image.open(bg_image) if bg_image else None, update_streamlit=realtime_update, height=150, drawing_mode=drawing_mode, point_display_radius=point_display_radius if drawing_mode == 'point' else 0, key="canvas",)
-```
-
-
-
-
-
-
-
-#### Image Comparison
-
-Compare images with a slider using [JuxtaposeJS](https://juxtapose.knightlab.com/). Created by [@fcakyon](https://github.com/fcakyon).
-
-```python
-from streamlit_image_comparison import image_comparison
-
-image_comparison(img1="image1.jpg", img2="image2.jpg",)
-```
-
-
-
-
-
-
-
-#### Streamlit Cropper
-
-A simple image cropper for Streamlit. Created by [@turner-anderson](https://github.com/turner-anderson).
-
-```python
-from streamlit_cropper import st_cropper
-
-st_cropper(img, realtime_update=realtime_update, box_color=box_color, aspect_ratio=aspect_ratio)
-```
-
-
-
-
-
-
-
-#### Image Coordinates
-
-Get the coordinates of clicks on an image. Created by [@blackary](https://github.com/blackary/).
-
-```python
-from streamlit_image_coordinates import streamlit_image_coordinates
-
-streamlit_image_coordinates("https://placekitten.com/200/300")
-```
-
-
-
-
-
-
-
-#### Streamlit Lottie
-
-Integrate [Lottie](https://lottiefiles.com/) animations inside your Streamlit app. Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-lottie_hello = load_lottieurl("https://assets5.lottiefiles.com/packages/lf20_V9t630.json")
-
-st_lottie(lottie_hello, key="hello")
-```
-
-
-
-
-
-## Layouts and containers
-
-
-
-
-
-
-#### Sidebar
-
-Display items in a sidebar.
-
-```python
-st.sidebar.write("This lives in the sidebar")
-st.sidebar.button("Click me!")
-```
-
-
-
-
-
-
-#### Columns
-
-Insert containers laid out as side-by-side columns.
-
-```python
-col1, col2 = st.columns(2)
-col1.write("this is column 1")
-col2.write("this is column 2")
-```
-
-
-
-
-
-
-#### Tabs
-
-Insert containers separated into tabs.
-
-```python
-tab1, tab2 = st.tabs(["Tab 1", "Tab2"])
-tab1.write("this is tab 1")
-tab2.write("this is tab 2")
-```
-
-
-
-
-
-
-#### Expander
-
-Insert a multi-element container that can be expanded/collapsed.
-
-```python
-with st.expander("Open to see more"):
- st.write("This is more content")
-```
-
-
-
-
-
-
-#### Container
-
-Insert a multi-element container.
-
-```python
-c = st.container()
-st.write("This will show last")
-c.write("This will show first")
-c.write("This will show second")
-```
-
-
-
-
-
-
-#### Empty
-
-Insert a single-element container.
-
-```python
-c = st.empty()
-st.write("This will show last")
-c.write("This will be replaced")
-c.write("This will show first")
-```
-
-
-
-
-
-
-
-
-
-
-#### Streamlit Elements
-
-Create a draggable and resizable dashboard in Streamlit. Created by [@okls](https://github.com/okls).
-
-```python
-from streamlit_elements import elements, mui, html
-
-with elements("new_element"):
- mui.Typography("Hello world")
-```
-
-
-
-
-
-
-
-#### Pydantic
-
-Auto-generate Streamlit UI from Pydantic Models and Dataclasses. Created by [@lukasmasuch](https://github.com/lukasmasuch).
-
-```python
-import streamlit_pydantic as sp
-
-sp.pydantic_form(key="my_form",
- model=ExampleModel)
-```
-
-
-
-
-
-
-
-#### Streamlit Pages
-
-An experimental version of Streamlit Multi-Page Apps. Created by [@blackary](https://github.com/blackary).
-
-```python
-from st_pages import Page, show_pages, add_page_title
-
-show_pages([ Page("streamlit_app.py", "Home", "🏠"),
- Page("other_pages/page2.py", "Page 2", ":books:"), ])
-```
-
-
-
-
-
-## Chat elements
-
-Streamlit provides a few commands to help you build conversational apps. These chat elements are designed to be used in conjunction with each other, but you can also use them separately.
-
-`st.chat_message` lets you insert a chat message container into the app so you can display messages from the user or the app. Chat containers can contain other Streamlit elements, including charts, tables, text, and more. `st.chat_input` lets you display a chat input widget so the user can type in a message.
-
-
-
-
-
-
-#### Chat message
-
-Insert a chat message container.
-
-```python
-import numpy as np
-with st.chat_message("user"):
- st.write("Hello 👋")
- st.line_chart(np.random.randn(30, 3))
-```
-
-
-
-
-
-
-#### Chat input
-
-Display a chat input widget.
-
-```python
-prompt = st.chat_input("Say something")
-if prompt:
- st.write(f"The user has sent: {prompt}")
-```
-
-
-
-
-## Display progress and status
-
-
-
-
-
-
-#### Progress bar
-
-Display a progress bar.
-
-```python
-for i in range(101):
- st.progress(i)
- do_something_slow()
-```
-
-
-
-
-
-
-#### Spinner
-
-Temporarily displays a message while executing a block of code.
-
-```python
-with st.spinner("Please wait..."):
- do_something_slow()
-```
-
-
-
-
-
-
-#### Toast
-
-Briefly displays a toast message in the bottom-right corner.
-
-```python
-st.toast('Butter!', icon='🧈')
-```
-
-
-
-
-
-
-#### Balloons
-
-Display celebratory balloons!
-
-```python
-do_something()
-
-# Celebrate when all done!
-st.balloons()
-```
-
-
-
-
-
-
-#### Snowflakes
-
-Display celebratory snowflakes!
-
-```python
-do_something()
-
-# Celebrate when all done!
-st.snow()
-```
-
-
-
-
-
-
-#### Error box
-
-Display error message.
-
-```python
-st.error("We encountered an error")
-```
-
-
-
-
-
-
-#### Warning box
-
-Display warning message.
-
-```python
-st.warning("Unable to fetch image. Skipping...")
-```
-
-
-
-
-
-
-#### Info box
-
-Display an informational message.
-
-```python
-st.info("Dataset is updated every day at midnight.")
-```
-
-
-
-
-
-
-#### Success box
-
-Display a success message.
-
-```python
-st.success("Match found!")
-```
-
-
-
-
-
-
-#### Exception output
-
-Display an exception.
-
-```python
-e = RuntimeError("This is an exception of type RuntimeError")
-st.exception(e)
-```
-
-
-
-
-
-
-
-
-
-
-
-#### Stqdm
-
-The simplest way to handle a progress bar in streamlit app. Created by [@Wirg](https://github.com/Wirg).
-
-```python
-from stqdm import stqdm
-
-for _ in stqdm(range(50)):
- sleep(0.5)
-```
-
-
-
-
-
-
-
-#### Custom notification box
-
-A custom notification box with the ability to close it out. Created by [@Socvest](https://github.com/Socvest).
-
-```python
-from streamlit_custom_notification_box import custom_notification_box
-
-styles = {'material-icons':{'color': 'red'}, 'text-icon-link-close-container': {'box-shadow': '#3896de 0px 4px'}, 'notification-text': {'':''}, 'close-button':{'':''}, 'link':{'':''}}
-custom_notification_box(icon='info', textDisplay='We are almost done with your registration...', externalLink='more info', url='#', styles=styles, key="foo")
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-from streamlit_extras.let_it_rain import rain
-
-rain(emoji="🎈", font_size=54,
- falling_speed=5, animation_length="infinite",)
-```
-
-
-
-
-
-## Control flow
-
-
-
-
-
-
-#### Forms
-
-Create a form that batches elements together with a “Submit" button.
-
-```python
-with st.form(key='my_form'):
- username = st.text_input("Username")
- password = st.text_input("Password")
- st.form_submit_button("Login")
-```
-
-
-
-
-#### Stop execution
-
-Stops execution immediately.
-
-```python
-st.stop()
-```
-
-
-
-
-#### Rerun script
-
-Rerun the script immediately.
-
-```python
-st.experimental_rerun()
-```
-
-
-
-
-
-
-
-
-
-
-#### Autorefresh
-
-Force a refresh without tying up a script. Created by [@kmcgrady](https://github.com/kmcgrady).
-
-```python
-from streamlit_autorefresh import st_autorefresh
-
-st_autorefresh(interval=2000, limit=100,
- key="fizzbuzzcounter")
-```
-
-
-
-
-
-
-
-#### Pydantic
-
-Auto-generate Streamlit UI from Pydantic Models and Dataclasses. Created by [@lukasmasuch](https://github.com/lukasmasuch).
-
-```python
-import streamlit_pydantic as sp
-
-sp.pydantic_form(key="my_form",
- model=ExampleModel)
-```
-
-
-
-
-
-
-
-#### Streamlit Pages
-
-An experimental version of Streamlit Multi-Page Apps. Created by [@blackary](https://github.com/blackary).
-
-```python
-from st_pages import Page, show_pages, add_page_title
-
-show_pages([ Page("streamlit_app.py", "Home", "🏠"),
- Page("other_pages/page2.py", "Page 2", ":books:"), ])
-```
-
-
-
-
-
-## Developer tools
-
-
-
-
-
-
-
-#### Pandas Profiling
-
-Pandas profiling component for Streamlit. Created by [@okld](https://github.com/okld/).
-
-```python
-df = pd.read_csv("https://storage.googleapis.com/tf-datasets/titanic/train.csv")
-pr = df.profile_report()
-
-st_profile_report(pr)
-```
-
-
-
-
-
-
-
-#### Streamlit Ace
-
-Ace editor component for Streamlit. Created by [@okld](https://github.com/okld).
-
-```python
-from streamlit_ace import st_ace
-
-content = st_ace()
-content
-```
-
-
-
-
-
-
-
-#### Streamlit Anaylitics
-
-Track & visualize user interactions with your streamlit app. Created by [@jrieke](https://github.com/jrieke).
-
-```python
-import streamlit_analytics
-
-with streamlit_analytics.track():
- st.text_input("Write something")
-```
-
-
-
-
-
-## Utilities
-
-
-
-
-#### Set page title, favicon, and more
-
-Configures the default settings of the page.
-
-```python
-st.set_page_config(
- page_title="My app",
- page_icon=":shark:",
-)
-```
-
-
-
-
-
-
-#### Echo
-
-Display some code on the app, then execute it. Useful for tutorials.
-
-```python
-with st.echo():
- st.write('This code will be printed')
-```
-
-
-
-
-#### Get help
-
-Display object’s doc string, nicely formatted.
-
-```python
-st.help(st.write)
-st.help(pd.DataFrame)
-```
-
-
-
-
-#### Get query parameters
-
-Return the query parameters that are currently showing in the browser's URL bar.
-
-```python
-st.experimental_get_query_params()
-```
-
-
-
-
-#### Set query parameters
-
-Set the query parameters that are shown in the browser's URL bar.
-
-```python
-st.experimental_set_query_params(
- show_map=True,
- selected=["asia"]
-)
-```
-
-
-
-
-## Mutate charts
-
-
-
-
-#### Add rows
-
-Append a dataframe to the bottom of the current one in certain elements, for optimized data updates.
-
-```python
-element = st.line_chart(df)
-element.add_rows(df_with_extra_rows)
-```
-
-
-
-
-## State management
-
-
-
-
-#### Session state
-
-Session state is a way to share variables between reruns, for each user session.
-
-```python
-st.session_state['key'] = value
-```
-
-
-
-
-## Connections and databases
-
-
-
-
-
-
-
-#### Authenticator
-
-A secure authentication module to validate user credentials. Created by [@mkhorasani](https://github.com/mkhorasani).
-
-```python
-import streamlit_authenticator as stauth
-
-authenticator = stauth.Authenticate( config['credentials'], config['cookie']['name'],
-config['cookie']['key'], config['cookie']['expiry_days'], config['preauthorized'])
-```
-
-
-
-
-
-
-
-#### WS localStorage
-
-A simple synchronous way of accessing localStorage from your app. Created by [@gagangoku](https://github.com/gagangoku).
-
-```python
-from streamlit_ws_localstorage import injectWebsocketCode
-
-ret = conn.setLocalStorageVal(key='k1', val='v1')
-st.write('ret: ' + ret)
-```
-
-
-
-
-
-
-
-#### Streamlit Auth0
-
-The fastest way to provide comprehensive login inside Streamlit. Created by [@conradbez](https://github.com/conradbez).
-
-```python
-from auth0_component import login_button
-
-user_info = login_button(clientId, domain = domain)
-st.write(user_info)
-```
-
-
-
-
-
-## Performance
-
-
-
-
-#### Cache data
-
-Function decorator to cache functions that return data (e.g. dataframe transforms, database queries, ML inference).
-
-```python
-@st.cache_data
-def long_function(param1, param2):
- # Perform expensive computation here or
- # fetch data from the web here
- return data
-```
-
-
-
-
-
-#### Cache resource
-
-Function decorator to cache functions that return global resources (e.g. database connections, ML models).
-
-```python
-@st.cache_resource
-def init_model():
- # Return a global resource here
- return pipeline(
- "sentiment-analysis",
- model="distilbert-base-uncased-finetuned-sst-2-english"
- )
-```
-
-
-
-
-
-#### Clear cached data
-
-Clear all in-memory and on-disk data caches.
-
-```python
-@st.cache_data
-def long_function(param1, param2):
- # Perform expensive computation here or
- # fetch data from the web here
- return data
-
-if st.checkbox("Clear All"):
- # Clear values from *all* cache_data functions
- st.cache_data.clear()
-```
-
-
-
-
-
-#### Clear cached resources
-
-Clear all `st.cache_resource` caches.
-
-```python
-@st.cache_resource
-def init_model():
- # Return a global resource here
- return pipeline(
- "sentiment-analysis",
- model="distilbert-base-uncased-finetuned-sst-2-english"
- )
-
-if st.checkbox("Clear All"):
- # Clear values from *all* cache_resource functions
- st.cache_data.clear()
-```
-
-
-
-
-
-## Connections and databases
-
-### Setup your connection
-
-
-
-
-
-
-#### Create a connection
-
-Connect to a data source or API
-
-```python
-conn = st.experimental_connection('pets_db', type='sql')
-pet_owners = conn.query('select * from pet_owners')
-st.dataframe(pet_owners)
-```
-
-
-
-
-### Built-in connections
-
-
-
-
-
-
-
-#### SQLConnection
-
-A connection to a SQL database using SQLAlchemy.
-
-```python
-conn = st.experimental_connection('sql')
-```
-
-
-
-
-
-
-
-#### SnowparkConnection
-
-A connection to Snowflake Snowpark.
-
-```python
-conn = st.experimental_connection('snowpark')
-```
-
-
-
-
-### Third-party connections
-
-
-
-
-#### Connection base class
-
-Build your own connection with `ExperimentalBaseConnection`.
-
-```python
-class MyConnection(ExperimentalBaseConnection[myconn.MyConnection]):
- def _connect(self, **kwargs) -> MyConnection:
- return myconn.connect(**self._secrets, **kwargs)
- def query(self, query):
- return self._instance.query(query)
-```
-
-
-
-
-
-## Personalization
-
-
-
-
-#### User info
-
-`st.experimental_user` returns information about the logged-in user of private apps on Streamlit Community Cloud.
-
-```python
-if st.experimental_user.email == "foo@corp.com":
- st.write("Welcome back, ", st.experimental_user.email)
-else:
- st.write("You are not authorized to view this page.")
-```
-
-
-
diff --git a/data/library/api/charts/altair_chart.md b/data/library/api/charts/altair_chart.md
deleted file mode 100644
index 8a3c283e3..000000000
--- a/data/library/api/charts/altair_chart.md
+++ /dev/null
@@ -1,266 +0,0 @@
----
-title: st.altair_chart
-slug: /library/api-reference/charts/st.altair_chart
-description: st.altair_chart displays a chart using the Altair library.
----
-
-
-
-### Theming
-
-Altair charts are displayed using the Streamlit theme by default. This theme is sleek, user-friendly, and incorporates Streamlit's color palette. The added benefit is that your charts better integrate with the rest of your app's design.
-
-The Streamlit theme is available from Streamlit 1.16.0 through the `theme="streamlit"` keyword argument. To disable it, and use Altair's native theme, use `theme=None` instead.
-
-Let's look at an example of charts with the Streamlit theme and the native Altair theme:
-
-```python
-import altair as alt
-from vega_datasets import data
-
-source = data.cars()
-
-chart = alt.Chart(source).mark_circle().encode(
- x='Horsepower',
- y='Miles_per_Gallon',
- color='Origin',
-).interactive()
-
-tab1, tab2 = st.tabs(["Streamlit theme (default)", "Altair native theme"])
-
-with tab1:
- # Use the Streamlit theme.
- # This is the default. So you can also omit the theme argument.
- st.altair_chart(chart, theme="streamlit", use_container_width=True)
-with tab2:
- # Use the native Altair theme.
- st.altair_chart(chart, theme=None, use_container_width=True)
-```
-
-Click the tabs in the interactive app below to see the charts with the Streamlit theme enabled and disabled.
-
-
-
-If you're wondering if your own customizations will still be taken into account, don't worry! You can still make changes to your chart configurations. In other words, although we now enable the Streamlit theme by default, you can overwrite it with custom colors or fonts. For example, if you want a chart line to be green instead of the default red, you can do it!
-
-Here's an example of an Altair chart where manual color passing is done and reflected:
-
-
-
-```python
-import altair as alt
-import streamlit as st
-from vega_datasets import data
-
-source = data.seattle_weather()
-
-scale = alt.Scale(
- domain=["sun", "fog", "drizzle", "rain", "snow"],
- range=["#e7ba52", "#a7a7a7", "#aec7e8", "#1f77b4", "#9467bd"],
-)
-color = alt.Color("weather:N", scale=scale)
-
-# We create two selections:
-# - a brush that is active on the top panel
-# - a multi-click that is active on the bottom panel
-brush = alt.selection_interval(encodings=["x"])
-click = alt.selection_multi(encodings=["color"])
-
-# Top panel is scatter plot of temperature vs time
-points = (
- alt.Chart()
- .mark_point()
- .encode(
- alt.X("monthdate(date):T", title="Date"),
- alt.Y(
- "temp_max:Q",
- title="Maximum Daily Temperature (C)",
- scale=alt.Scale(domain=[-5, 40]),
- ),
- color=alt.condition(brush, color, alt.value("lightgray")),
- size=alt.Size("precipitation:Q", scale=alt.Scale(range=[5, 200])),
- )
- .properties(width=550, height=300)
- .add_selection(brush)
- .transform_filter(click)
-)
-
-# Bottom panel is a bar chart of weather type
-bars = (
- alt.Chart()
- .mark_bar()
- .encode(
- x="count()",
- y="weather:N",
- color=alt.condition(click, color, alt.value("lightgray")),
- )
- .transform_filter(brush)
- .properties(
- width=550,
- )
- .add_selection(click)
-)
-
-chart = alt.vconcat(points, bars, data=source, title="Seattle Weather: 2012-2015")
-
-tab1, tab2 = st.tabs(["Streamlit theme (default)", "Altair native theme"])
-
-with tab1:
- st.altair_chart(chart, theme="streamlit", use_container_width=True)
-with tab2:
- st.altair_chart(chart, theme=None, use_container_width=True)
-```
-
-
-
-Notice how the custom colors are still reflected in the chart, even when the Streamlit theme is enabled 👇
-
-
-
-For many more examples of Altair charts with and without the Streamlit theme, check out the [altair.streamlit.app](https://altair.streamlit.app).
-
-### Annotating charts
-
-Altair also allows you to annotate your charts with text, images, and emojis. You can do this by creating [layered charts](https://altair-viz.github.io/user_guide/compound_charts.html#layered-charts), which let you overlay two different charts on top of each other. The idea is to use the first chart to show the data, and the second chart to show the annotations. The second chart can then be overlaid on top of the first chart using the `+` operator to create a layered chart.
-
-Let's walk through an example of annotating a time-series chart with text and an emoji.
-
-#### Step 1: Create the base chart
-
-In this example, we create a time-series chart to track the evolution of stock prices. The chart is interactive and contains a multi-line tooltip. Click [here](https://altair-viz.github.io/gallery/multiline_tooltip.html) to learn more about multi-line tooltips in Altair.
-
-First, we import the required libraries and load the example stocks dataset using the [`vega_datasets`](https://pypi.org/project/vega-datasets/) package:
-
-```python
-import altair as alt
-import pandas as pd
-import streamlit as st
-from vega_datasets import data
-
-# We use @st.cache_data to keep the dataset in cache
-@st.cache_data
-def get_data():
- source = data.stocks()
- source = source[source.date.gt("2004-01-01")]
- return source
-
-source = get_data()
-```
-
-Next, we define a function `get_chart()` to create the interactive time-series chart of the stock prices with a multi-line tooltip. The x-axis represents the date, and the y-axis represents the stock price.
-
-We then invoke `get_chart()` that takes the stock prices dataframe as an input and returns a chart object. This is going to be our base chart on which we will overlay the annotations in [Step 2](/library/api-reference/charts/st.altair_chart#step-2-annotate-the-chart).
-
-```python
-# Define the base time-series chart.
-def get_chart(data):
- hover = alt.selection_single(
- fields=["date"],
- nearest=True,
- on="mouseover",
- empty="none",
- )
-
- lines = (
- alt.Chart(data, title="Evolution of stock prices")
- .mark_line()
- .encode(
- x="date",
- y="price",
- color="symbol",
- )
- )
-
- # Draw points on the line, and highlight based on selection
- points = lines.transform_filter(hover).mark_circle(size=65)
-
- # Draw a rule at the location of the selection
- tooltips = (
- alt.Chart(data)
- .mark_rule()
- .encode(
- x="yearmonthdate(date)",
- y="price",
- opacity=alt.condition(hover, alt.value(0.3), alt.value(0)),
- tooltip=[
- alt.Tooltip("date", title="Date"),
- alt.Tooltip("price", title="Price (USD)"),
- ],
- )
- .add_selection(hover)
- )
- return (lines + points + tooltips).interactive()
-
-chart = get_chart(source)
-```
-
-#### Step 2: Annotate the chart
-
-Now that we have our first chart that shows the data, we can annotate it with text and an emoji. Let's overlay the ⬇ emoji on top of the time-series chart at specifc points of interest. We want users to hover over the ⬇ emoji to see the associated annotation text.
-
-For simplicity, let's annotate four specific dates and set the height of the annotations at constant value of `10`.
-
-
-
-You can vary the horizontal and vertical postions of the annotations by replacing the hard-coded values with the output of Streamlit widgets! Click [here](/library/api-reference/charts/st.altair_chart#interactive-example) to jump to a live example below, and develop an intuition for the ideal horizontal and vertical positions of the annotations by playing with Streamlit widgets.
-
-
-
-To do so, we create a dataframe `annotations_df` containing the dates, annotation text, and the height of the annotations:
-
-```python
-# Add annotations
-ANNOTATIONS = [
- ("Mar 01, 2008", "Pretty good day for GOOG"),
- ("Dec 01, 2007", "Something's going wrong for GOOG & AAPL"),
- ("Nov 01, 2008", "Market starts again thanks to..."),
- ("Dec 01, 2009", "Small crash for GOOG after..."),
-]
-annotations_df = pd.DataFrame(ANNOTATIONS, columns=["date", "event"])
-annotations_df.date = pd.to_datetime(annotations_df.date)
-annotations_df["y"] = 10
-```
-
-Using this dataframe, we create a scatter plot with the x-axis representing the date, and the y-axis representing the height of the annotation. The data point at the specific date and height is represented by the ⬇ emoji, using Altair's `mark_text()` [mark](https://altair-viz.github.io/user_guide/marks.html).
-
-The annotation text is displayed as a tooltip when users hover over the ⬇ emoji. This is achieved using Altair's `encode()` method to map the `event` column containing the annotation text to the visual attribute ⬇ of the plot.
-
-```python
-annotation_layer = (
- alt.Chart(annotations_df)
- .mark_text(size=20, text="⬇", dx=-8, dy=-10, align="left")
- .encode(
- x="date:T",
- y=alt.Y("y:Q"),
- tooltip=["event"],
- )
- .interactive()
-)
-```
-
-Finally, we overlay the annotations on top of the base chart using the `+` operator to create the final layered chart! 🎈
-
-```python
-st.altair_chart(
- (chart + annotation_layer).interactive(),
- use_container_width=True
-)
-```
-
-
-
-To use images instead of emojis, replace the line containing `.mark_text()` with `.mark_image()`, and replace `image_url` below with the URL of the image:
-
-```python
-.mark_image(
- width=12,
- height=12,
- url="image_url",
-)
-```
-
-#### Interactive example
-
-Now that you've learned how to annotate charts, the sky's the limit! We've extended the above example to let you interactively paste your favorite emoji and set its position on the chart with Streamlit widgets. 👇
-
-
diff --git a/data/library/api/charts/area_chart.md b/data/library/api/charts/area_chart.md
deleted file mode 100644
index ac834cd70..000000000
--- a/data/library/api/charts/area_chart.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.area_chart
-slug: /library/api-reference/charts/st.area_chart
-description: st.area_chart displays an area chart.
----
-
-
diff --git a/data/library/api/charts/bar_chart.md b/data/library/api/charts/bar_chart.md
deleted file mode 100644
index 20b8899a4..000000000
--- a/data/library/api/charts/bar_chart.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.bar_chart
-slug: /library/api-reference/charts/st.bar_chart
-description: st.bar_chart displays a bar chart.
----
-
-
diff --git a/data/library/api/charts/bokeh_chart.md b/data/library/api/charts/bokeh_chart.md
deleted file mode 100644
index 10a57efde..000000000
--- a/data/library/api/charts/bokeh_chart.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.bokeh_chart
-slug: /library/api-reference/charts/st.bokeh_chart
-description: st.bokeh_chart displays an interactive Bokeh chart.
----
-
-
diff --git a/data/library/api/charts/charts.md b/data/library/api/charts/charts.md
deleted file mode 100644
index 9b3fe0d1f..000000000
--- a/data/library/api/charts/charts.md
+++ /dev/null
@@ -1,289 +0,0 @@
----
-title: Chart elements
-slug: /library/api-reference/charts
----
-
-# Chart elements
-
-Streamlit supports several different charting libraries, and our goal is to
-continually add support for more. Right now, the most basic library in our
-arsenal is [Matplotlib](https://matplotlib.org/). Then there are also
-interactive charting libraries like [Vega
-Lite](https://vega.github.io/vega-lite/) (2D charts) and
-[deck.gl](https://github.com/uber/deck.gl) (maps and 3D charts). And
-finally we also provide a few chart types that are "native" to Streamlit,
-like `st.line_chart` and `st.area_chart`.
-
-
-
-
-
-#### Simple line charts
-
-Display a line chart.
-
-```python
-st.line_chart(my_data_frame)
-```
-
-
-
-
-
-#### Simple area charts
-
-Display an area chart.
-
-```python
-st.area_chart(my_data_frame)
-```
-
-
-
-
-
-#### Simple bar charts
-
-Display a bar chart.
-
-```python
-st.bar_chart(my_data_frame)
-```
-
-
-
-
-
-#### Scatterplots on maps
-
-Display a map with points on it.
-
-```python
-st.map(my_data_frame)
-```
-
-
-
-
-
-#### Matplotlib
-
-Display a matplotlib.pyplot figure.
-
-```python
-st.pyplot(my_mpl_figure)
-```
-
-
-
-
-
-#### Altair
-
-Display a chart using the Altair library.
-
-```python
-st.altair_chart(my_altair_chart)
-```
-
-
-
-
-
-#### Vega-Lite
-
-Display a chart using the Vega-Lite library.
-
-```python
-st.vega_lite_chart(my_vega_lite_chart)
-```
-
-
-
-
-
-#### Plotly
-
-Display an interactive Plotly chart.
-
-```python
-st.plotly_chart(my_plotly_chart)
-```
-
-
-
-
-
-#### Bokeh
-
-Display an interactive Bokeh chart.
-
-```python
-st.bokeh_chart(my_bokeh_chart)
-```
-
-
-
-
-
-#### PyDeck
-
-Display a chart using the PyDeck library.
-
-```python
-st.pydeck_chart(my_pydeck_chart)
-```
-
-
-
-
-
-#### GraphViz
-
-Display a graph using the dagre-d3 library.
-
-```python
-st.graphviz_chart(my_graphviz_spec)
-```
-
-
-
-
-
-
-
-
-
-
-#### Plost
-
-A deceptively simple plotting library for Streamlit. Created by [@tvst](https://github.com/tvst).
-
-```python
-import plost
-plost.line_chart(my_dataframe, x='time', y='stock_value', color='stock_name',)
-```
-
-
-
-
-
-
-
-#### HiPlot
-
-High dimensional Interactive Plotting. Created by [@facebookresearch](https://github.com/facebookresearch).
-
-```python
-data = [{'dropout':0.1, 'lr': 0.001, 'loss': 10.0, 'optimizer': 'SGD'}, {'dropout':0.15, 'lr': 0.01, 'loss': 3.5, 'optimizer': 'Adam'}, {'dropout':0.3, 'lr': 0.1, 'loss': 4.5, 'optimizer': 'Adam'}]
-hip.Experiment.from_iterable(data).display()
-```
-
-
-
-
-
-
-
-#### ECharts
-
-High dimensional Interactive Plotting. Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-from streamlit_echarts import st_echarts
-st_echarts(options=options)
-```
-
-
-
-
-
-
-
-#### Streamlit Folium
-
-Streamlit Component for rendering Folium maps. Created by [@randyzwitch](https://github.com/randyzwitch).
-
-```python
-m = folium.Map(location=[39.949610, -75.150282], zoom_start=16)
-st_data = st_folium(m, width=725)
-```
-
-
-
-
-
-
-
-#### Spacy-Streamlit
-
-spaCy building blocks and visualizers for Streamlit apps. Created by [@explosion](https://github.com/explosion).
-
-```python
-models = ["en_core_web_sm", "en_core_web_md"]
-spacy_streamlit.visualize(models, "Sundar Pichai is the CEO of Google.")
-```
-
-
-
-
-
-
-
-#### Streamlit Agraph
-
-A Streamlit Graph Vis, based on [react-grah-vis](https://github.com/crubier/react-graph-vis). Created by [@ChrisDelClea](https://github.com/ChrisDelClea).
-
-```python
-from streamlit_agraph import agraph, Node, Edge, Config
-agraph(nodes=nodes, edges=edges, config=config)
-```
-
-
-
-
-
-
-
-#### Streamlit Lottie
-
-Integrate [Lottie](https://lottiefiles.com/) animations inside your Streamlit app. Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-lottie_hello = load_lottieurl("https://assets5.lottiefiles.com/packages/lf20_V9t630.json")
-st_lottie(lottie_hello, key="hello")
-```
-
-
-
-
-
-
-
-#### Plotly Events
-
-Make Plotly charts interactive!. Created by [@null-jones](https://github.com/null-jones/).
-
-```python
-fig = px.line(x=[1], y=[1])
-selected_points = plotly_events(fig)
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-chart += get_annotations_chart(annotations=[("Mar 01, 2008", "Pretty good day for GOOG"), ("Dec 01, 2007", "Something's going wrong for GOOG & AAPL"), ("Nov 01, 2008", "Market starts again thanks to..."), ("Dec 01, 2009", "Small crash for GOOG after..."),],)
-st.altair_chart(chart, use_container_width=True)
-```
-
-
-
-
diff --git a/data/library/api/charts/graphviz_chart.md b/data/library/api/charts/graphviz_chart.md
deleted file mode 100644
index 9ca464f10..000000000
--- a/data/library/api/charts/graphviz_chart.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.graphviz_chart
-slug: /library/api-reference/charts/st.graphviz_chart
-description: st.graphviz_chart displays a graph using the dagre-d3 library.
----
-
-
diff --git a/data/library/api/charts/line_chart.md b/data/library/api/charts/line_chart.md
deleted file mode 100644
index 5023daa55..000000000
--- a/data/library/api/charts/line_chart.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.line_chart
-slug: /library/api-reference/charts/st.line_chart
-description: st.line_chart displays a line chart.
----
-
-
diff --git a/data/library/api/charts/map.md b/data/library/api/charts/map.md
deleted file mode 100644
index 698801612..000000000
--- a/data/library/api/charts/map.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.map
-slug: /library/api-reference/charts/st.map
-description: st.map displays a map with points on it.
----
-
-
diff --git a/data/library/api/charts/plotly_chart.md b/data/library/api/charts/plotly_chart.md
deleted file mode 100644
index 00772b003..000000000
--- a/data/library/api/charts/plotly_chart.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-title: st.plotly_chart
-slug: /library/api-reference/charts/st.plotly_chart
-description: st.plotly_chart displays an interactive Plotly chart.
----
-
-
-
-### Theming
-
-Plotly charts are displayed using the Streamlit theme by default. This theme is sleek, user-friendly, and incorporates Streamlit's color palette. The added benefit is that your charts better integrate with the rest of your app's design.
-
-The Streamlit theme is available from Streamlit 1.16.0 through the `theme="streamlit"` keyword argument. To disable it, and use Plotly's native theme, use `theme=None` instead.
-
-Let's look at an example of charts with the Streamlit theme and the native Plotly theme:
-
-```python
-import plotly.express as px
-import streamlit as st
-
-df = px.data.gapminder()
-
-fig = px.scatter(
- df.query("year==2007"),
- x="gdpPercap",
- y="lifeExp",
- size="pop",
- color="continent",
- hover_name="country",
- log_x=True,
- size_max=60,
-)
-
-tab1, tab2 = st.tabs(["Streamlit theme (default)", "Plotly native theme"])
-with tab1:
- # Use the Streamlit theme.
- # This is the default. So you can also omit the theme argument.
- st.plotly_chart(fig, theme="streamlit", use_container_width=True)
-with tab2:
- # Use the native Plotly theme.
- st.plotly_chart(fig, theme=None, use_container_width=True)
-```
-
-Click the tabs in the interactive app below to see the charts with the Streamlit theme enabled and disabled.
-
-
-
-If you're wondering if your own customizations will still be taken into account, don't worry! You can still make changes to your chart configurations. In other words, although we now enable the Streamlit theme by default, you can overwrite it with custom colors or fonts. For example, if you want a chart line to be green instead of the default red, you can do it!
-
-Here's an example of an Plotly chart where a custom color scale is defined and reflected:
-
-```python
-import plotly.express as px
-import streamlit as st
-
-st.subheader("Define a custom colorscale")
-df = px.data.iris()
-fig = px.scatter(
- df,
- x="sepal_width",
- y="sepal_length",
- color="sepal_length",
- color_continuous_scale="reds",
-)
-
-tab1, tab2 = st.tabs(["Streamlit theme (default)", "Plotly native theme"])
-with tab1:
- st.plotly_chart(fig, theme="streamlit", use_container_width=True)
-with tab2:
- st.plotly_chart(fig, theme=None, use_container_width=True)
-```
-
-Notice how the custom color scale is still reflected in the chart, even when the Streamlit theme is enabled 👇
-
-
-
-For many more examples of Plotly charts with and without the Streamlit theme, check out the [plotly.streamlit.app](https://plotly.streamlit.app).
diff --git a/data/library/api/charts/pydeck_chart.md b/data/library/api/charts/pydeck_chart.md
deleted file mode 100644
index 2131ab6b4..000000000
--- a/data/library/api/charts/pydeck_chart.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.pydeck_chart
-slug: /library/api-reference/charts/st.pydeck_chart
-description: st.pydeck_chart displays a chart using the PyDeck library.
----
-
-
diff --git a/data/library/api/charts/pyplot.md b/data/library/api/charts/pyplot.md
deleted file mode 100644
index ef81d2756..000000000
--- a/data/library/api/charts/pyplot.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.pyplot
-slug: /library/api-reference/charts/st.pyplot
-description: st.pyplot displays a matplotlib.pyplot figure.
----
-
-
diff --git a/data/library/api/charts/vega_lite_chart.md b/data/library/api/charts/vega_lite_chart.md
deleted file mode 100644
index aa008e341..000000000
--- a/data/library/api/charts/vega_lite_chart.md
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: st.vega_lite_chart
-slug: /library/api-reference/charts/st.vega_lite_chart
-description: st.vega_lite_chart displays a chart using the Vega-Lite library.
----
-
-
-
-### Theming
-
-Vega-Lite charts are displayed using the Streamlit theme by default. This theme is sleek, user-friendly, and incorporates Streamlit's color palette. The added benefit is that your charts better integrate with the rest of your app's design.
-
-The Streamlit theme is available from Streamlit 1.16.0 through the `theme="streamlit"` keyword argument. To disable it, and use Vega-Lite's native theme, use `theme=None` instead.
-
-Let's look at an example of charts with the Streamlit theme and the native Vega-Lite theme:
-
-```python
-import streamlit as st
-from vega_datasets import data
-
-source = data.cars()
-
-chart = {
- "mark": "point",
- "encoding": {
- "x": {
- "field": "Horsepower",
- "type": "quantitative",
- },
- "y": {
- "field": "Miles_per_Gallon",
- "type": "quantitative",
- },
- "color": {"field": "Origin", "type": "nominal"},
- "shape": {"field": "Origin", "type": "nominal"},
- },
-}
-
-tab1, tab2 = st.tabs(["Streamlit theme (default)", "Vega-Lite native theme"])
-
-with tab1:
- # Use the Streamlit theme.
- # This is the default. So you can also omit the theme argument.
- st.vega_lite_chart(
- source, chart, theme="streamlit", use_container_width=True
- )
-with tab2:
- st.vega_lite_chart(
- source, chart, theme=None, use_container_width=True
- )
-```
-
-Click the tabs in the interactive app below to see the charts with the Streamlit theme enabled and disabled.
-
-
-
-If you're wondering if your own customizations will still be taken into account, don't worry! You can still make changes to your chart configurations. In other words, although we now enable the Streamlit theme by default, you can overwrite it with custom colors or fonts. For example, if you want a chart line to be green instead of the default red, you can do it!
diff --git a/data/library/api/chat/chat-input.md b/data/library/api/chat/chat-input.md
deleted file mode 100644
index 317798c4a..000000000
--- a/data/library/api/chat/chat-input.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: st.chat_input
-slug: /library/api-reference/chat/st.chat_input
-description: st.chat_input displays a chat input widget.
----
-
-
-
-Read the [Build conversational apps](/knowledge-base/tutorials/build-conversational-apps) tutorial to learn how to use `st.chat_message` and `st.chat_input` to build chat-based apps.
-
-
-
-
-
-For an overview of the `st.chat_input` and `st.chat_message` API, check out this video tutorial by Chanin Nantasenamat ([@dataprofessor](https://www.youtube.com/dataprofessor)), a Senior Developer Advocate at Streamlit.
-
-
diff --git a/data/library/api/chat/chat-message.md b/data/library/api/chat/chat-message.md
deleted file mode 100644
index 88726db9c..000000000
--- a/data/library/api/chat/chat-message.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: st.chat_message
-slug: /library/api-reference/chat/st.chat_message
-description: st.chat_message inserts a chat message container into the app.
----
-
-
-
-Read the [Build conversational apps](/knowledge-base/tutorials/build-conversational-apps) tutorial to learn how to use `st.chat_message` and `st.chat_input` to build chat-based apps.
-
-
-
-
-
-For an overview of the `st.chat_message` and `st.chat_input` API, check out this video tutorial by Chanin Nantasenamat ([@dataprofessor](https://www.youtube.com/dataprofessor)), a Senior Developer Advocate at Streamlit.
-
-
diff --git a/data/library/api/chat/chat.md b/data/library/api/chat/chat.md
deleted file mode 100644
index 1783a01b0..000000000
--- a/data/library/api/chat/chat.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: Chat elements
-slug: /library/api-reference/chat
----
-
-# Chat elements
-
-Streamlit provides a few commands to help you build conversational apps. These chat elements are designed to be used in conjunction with each other, but you can also use them separately.
-
-`st.chat_message` lets you insert a chat message container into the app so you can display messages from the user or the app. Chat containers can contain other Streamlit elements, including charts, tables, text, and more. `st.chat_input` lets you display a chat input widget so the user can type in a message.
-
-
-
-
-
-
-#### Chat message
-
-Insert a chat message container.
-
-```python
-import numpy as np
-with st.chat_message("user"):
- st.write("Hello 👋")
- st.line_chart(np.random.randn(30, 3))
-```
-
-
-
-
-
-
-#### Chat input
-
-Display a chat input widget.
-
-```python
-prompt = st.chat_input("Say something")
-if prompt:
- st.write(f"The user has sent: {prompt}")
-```
-
-
-
diff --git a/data/library/api/connections/connections-experimentalbaseconnection.md b/data/library/api/connections/connections-experimentalbaseconnection.md
deleted file mode 100644
index 1ddfcfe92..000000000
--- a/data/library/api/connections/connections-experimentalbaseconnection.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: st.connections.ExperimentalBaseConnection
-slug: /library/api-reference/connections/st.connections.experimentalbaseconnection
----
-
-
-
-This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
-
-
-
-
-
-This page only contains information on the `st.connections.ExperimentalBaseConnection` API. For a deeper dive into creating and managing data connections within Streamlit apps, read [Connecting to data](/library/advanced-features/connecting-to-data).
-
-
-
-
-
-
diff --git a/data/library/api/connections/connections-snowpark.md b/data/library/api/connections/connections-snowpark.md
deleted file mode 100644
index daded9697..000000000
--- a/data/library/api/connections/connections-snowpark.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: st.connections.SnowparkConnection
-slug: /library/api-reference/connections/st.connections.snowparkconnection
----
-
-
-
-This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
-
-
-
-
-
-This page only contains on the `st.connections.SnowparkConnection` API. For a deeper dive into creating and managing data connections within Streamlit apps, read [Connecting to data](/library/advanced-features/connecting-to-data).
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/data/library/api/connections/connections-sql.md b/data/library/api/connections/connections-sql.md
deleted file mode 100644
index fdf626887..000000000
--- a/data/library/api/connections/connections-sql.md
+++ /dev/null
@@ -1,74 +0,0 @@
----
-title: st.connections.SQLConnection
-slug: /library/api-reference/connections/st.connections.sqlconnection
----
-
-
-
-This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
-
-
-
-
-
-This page only contains on the `st.connections.SQLConnection` API. For a deeper dive into creating and managing data connections within Streamlit apps, read [Connecting to data](/library/advanced-features/connecting-to-data).
-
-
-
-
-
-### Basic usage:
-
-```python
-import streamlit as st
-
-conn = st.experimental_connection("sql")
-df = conn.query("select * from pet_owners")
-st.dataframe(df)
-```
-
-In case you want to pass a connection URL (or other parameters) directly, it also works:
-
-```python
-conn = st.experimental_connection(
- "local_db",
- type="sql",
- url="mysql://user:pass@localhost:3306/mydb"
-)
-```
-
-Or specify parameters in [secrets](/library/advanced-features/secrets-management):
-
-```toml
-# .streamlit/secrets.toml
-[connections.mydb]
-dialect = "mysql"
-username = "myuser"
-password = "password"
-host = "localhost"
-database = "mydb"
-```
-
-```python
-# streamlit_app.py
-conn = st.experimental_connection("mydb", type="sql", autocommit=True)
-```
-
-As described above, some cloud databases use extra `**kwargs` to specify credentials. These can be passed via secrets using the `create_engine_kwargs` section:
-
-```toml
-# .streamlit/secrets.toml
-[connections.snowflake]
-url = "snowflake://@/"
-
-[connections.snowflake.create_engine_kwargs.connect_args]
-authenticator = "externalbrowser"
-role = "..."
-# ...
-```
-
-
-
-
-
-
diff --git a/data/library/api/connections/connections.md b/data/library/api/connections/connections.md
deleted file mode 100644
index 8b6eeb650..000000000
--- a/data/library/api/connections/connections.md
+++ /dev/null
@@ -1,80 +0,0 @@
----
-title: Connections and databases
-slug: /library/api-reference/connections
----
-
-# Connections and databases
-
-## Setup your connection
-
-
-
-
-
-
-#### Create a connection
-
-Connect to a data source or API
-
-```python
-conn = st.experimental_connection('pets_db', type='sql')
-pet_owners = conn.query('select * from pet_owners')
-st.dataframe(pet_owners)
-```
-
-
-
-
-## Built-in connections
-
-
-
-
-
-
-
-#### SQLConnection
-
-A connection to a SQL database using SQLAlchemy.
-
-```python
-conn = st.experimental_connection('sql')
-```
-
-
-
-
-
-
-
-#### SnowparkConnection
-
-A connection to Snowflake Snowpark.
-
-```python
-conn = st.experimental_connection('snowpark')
-```
-
-
-
-
-## Third-party connections
-
-
-
-
-#### Connection base class
-
-Build your own connection with `ExperimentalBaseConnection`.
-
-```python
-class MyConnection(ExperimentalBaseConnection[myconn.MyConnection]):
- def _connect(self, **kwargs) -> MyConnection:
- return myconn.connect(**self._secrets, **kwargs)
- def query(self, query):
- return self._instance.query(query)
-```
-
-
-
-
diff --git a/data/library/api/connections/experimental-connection.md b/data/library/api/connections/experimental-connection.md
deleted file mode 100644
index b0bd86cf0..000000000
--- a/data/library/api/connections/experimental-connection.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: st.experimental_connection
-slug: /library/api-reference/connections/st.experimental_connection
----
-
-
-
-This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
-
-
-
-
-
-This page only contains on the `st.experimental_connection` API. For a deeper dive into creating and managing data connections within Streamlit apps, read [Connecting to data](/library/advanced-features/connecting-to-data).
-
-
-
-
-
-For a comprehensive overview of this feature, check out this video tutorial by Joshua Carroll, Streamlit's Product Manager for Developer Experience. You'll learn about the feature's utility in creating and managing data connections within your apps by using real-world examples.
-
-
diff --git a/data/library/api/control-flow/control-flow.md b/data/library/api/control-flow/control-flow.md
deleted file mode 100644
index 19efe3b44..000000000
--- a/data/library/api/control-flow/control-flow.md
+++ /dev/null
@@ -1,130 +0,0 @@
----
-title: Control flow
-slug: /library/api-reference/control-flow
----
-
-# Control flow
-
-## Change execution
-
-By default, Streamlit apps execute the script entirely, but we allow some functionality to handle control flow in your applications.
-
-
-
-
-#### Stop execution
-
-Stops execution immediately.
-
-```python
-st.stop()
-```
-
-
-
-
-
-#### Rerun script
-
-Rerun the script immediately.
-
-```python
-st.experimental_rerun()
-```
-
-
-
-
-## Group multiple widgets
-
-By default, Streamlit reruns your script everytime a user interacts with your app.
-However, sometimes it's a better user experience to wait until a group of related
-widgets is filled before actually rerunning the script. That's what `st.form` is for!
-
-
-
-
-#### Forms
-
-Create a form that batches elements together with a “Submit" button.
-
-```python
-with st.form(key="my_form"):
- username = st.text_input("Username")
- password = st.text_input("Password")
- st.form_submit_button("Login")
-```
-
-
-
-
-
-#### Form submit button
-
-Display a form submit button.
-
-```python
-with st.form(key="my_form"):
- username = st.text_input("Username")
- password = st.text_input("Password")
- st.form_submit_button("Login")
-```
-
-
-
-
-
-
-
-
-
-
-
-#### Autorefresh
-
-Force a refresh without tying up a script. Created by [@kmcgrady](https://github.com/kmcgrady).
-
-```python
-from streamlit_autorefresh import st_autorefresh
-
-st_autorefresh(interval=2000, limit=100,
- key="fizzbuzzcounter")
-```
-
-
-
-
-
-
-
-#### Pydantic
-
-Auto-generate Streamlit UI from Pydantic Models and Dataclasses. Created by [@lukasmasuch](https://github.com/lukasmasuch).
-
-```python
-import streamlit_pydantic as sp
-
-sp.pydantic_form(key="my_form",
- model=ExampleModel)
-```
-
-
-
-
-
-
-
-#### Streamlit Pages
-
-An experimental version of Streamlit Multi-Page Apps. Created by [@blackary](https://github.com/blackary).
-
-```python
-from st_pages import Page, show_pages, add_page_title
-
-show_pages([ Page("streamlit_app.py", "Home", "🏠"),
- Page("other_pages/page2.py", "Page 2", ":books:"), ])
-```
-
-
-
-
diff --git a/data/library/api/control-flow/experimental_rerun.md b/data/library/api/control-flow/experimental_rerun.md
deleted file mode 100644
index 4ccac0ff9..000000000
--- a/data/library/api/control-flow/experimental_rerun.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: st.experimental_rerun
-slug: /library/api-reference/control-flow/st.experimental_rerun
-description: st.experimental_rerun will rerun the script immediately.
----
-
-
-
-This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
-
-
-
-
diff --git a/data/library/api/control-flow/form.md b/data/library/api/control-flow/form.md
deleted file mode 100644
index 9665065e9..000000000
--- a/data/library/api/control-flow/form.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: st.form
-slug: /library/api-reference/control-flow/st.form
-description: st.form creates a form that batches elements together with a “Submit" button.
----
-
-
-
-This page only contains information on the `st.forms` API. For a deeper dive into creating and using forms within Streamlit apps, read our guide on [Using forms](/library/advanced-features/forms).
-
-
-
-
diff --git a/data/library/api/control-flow/form_submit_button.md b/data/library/api/control-flow/form_submit_button.md
deleted file mode 100644
index b7c13dadc..000000000
--- a/data/library/api/control-flow/form_submit_button.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.form_submit_button
-slug: /library/api-reference/control-flow/st.form_submit_button
-description: st.form_submit_button displays a form submit button.
----
-
-
diff --git a/data/library/api/control-flow/stop.md b/data/library/api/control-flow/stop.md
deleted file mode 100644
index d494f098a..000000000
--- a/data/library/api/control-flow/stop.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.stop
-slug: /library/api-reference/control-flow/st.stop
-description: st.stop stops the execution immediately.
----
-
-
diff --git a/data/library/api/data/column_config/barchartcolumn.md b/data/library/api/data/column_config/barchartcolumn.md
deleted file mode 100644
index 0da1a9c27..000000000
--- a/data/library/api/data/column_config/barchartcolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.BarChartColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.barchartcolumn
----
-
-
diff --git a/data/library/api/data/column_config/checkboxcolumn.md b/data/library/api/data/column_config/checkboxcolumn.md
deleted file mode 100644
index 6724b41a6..000000000
--- a/data/library/api/data/column_config/checkboxcolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.CheckboxColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.checkboxcolumn
----
-
-
diff --git a/data/library/api/data/column_config/column.md b/data/library/api/data/column_config/column.md
deleted file mode 100644
index af6f82030..000000000
--- a/data/library/api/data/column_config/column.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.Column
-slug: /library/api-reference/data/st.column_config/st.column_config.column
----
-
-
diff --git a/data/library/api/data/column_config/datecolumn.md b/data/library/api/data/column_config/datecolumn.md
deleted file mode 100644
index a1a85df0f..000000000
--- a/data/library/api/data/column_config/datecolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.DateColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.datecolumn
----
-
-
diff --git a/data/library/api/data/column_config/datetimecolumn.md b/data/library/api/data/column_config/datetimecolumn.md
deleted file mode 100644
index deff0f06b..000000000
--- a/data/library/api/data/column_config/datetimecolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.DatetimeColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.datetimecolumn
----
-
-
diff --git a/data/library/api/data/column_config/imagecolumn.md b/data/library/api/data/column_config/imagecolumn.md
deleted file mode 100644
index 6793b3eb3..000000000
--- a/data/library/api/data/column_config/imagecolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.ImageColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.imagecolumn
----
-
-
diff --git a/data/library/api/data/column_config/index.md b/data/library/api/data/column_config/index.md
deleted file mode 100644
index 64643836f..000000000
--- a/data/library/api/data/column_config/index.md
+++ /dev/null
@@ -1,193 +0,0 @@
----
-title: st.column_config
-slug: /library/api-reference/data/st.column_config
----
-
-# Column configuration
-
-When working with data in Streamlit, the `st.column_config` class is a powerful tool for configuring data display and interaction. Specifically designed for the `column_config` parameter in [`st.dataframe`](/library/api-reference/data/st.dataframe) and [`st.data_editor`](/library/api-reference/data/st.data_editor), it provides a suite of methods to tailor your columns to various data types - from simple text and numbers to lists, URLs, images, and more.
-
-Whether it's translating temporal data into user-friendly formats or utilizing charts and progress bars for clearer data visualization, column configuration not only provides the user with an enriched data viewing experience but also ensures that you're equipped with the tools to present and interact with your data, just the way you want it.
-
-
-
-
-
-#### Column
-
-Configure a generic column.
-
-```python
-Column("Streamlit Widgets", width="medium", help="Streamlit **widget** commands 🎈")
-```
-
-
-
-
-
-#### Text column
-
-Configure a text column.
-
-```python
-TextColumn("Widgets", max_chars=50, validate="^st\.[a-z_]+$")
-```
-
-
-
-
-
-
-#### Number column
-
-Configure a number column.
-
-```python
-NumberColumn("Price (in USD)", min_value=0, format="$%d")
-```
-
-
-
-
-
-
-#### Checkbox column
-
-Configure a checkbox column.
-
-```python
-CheckboxColumn("Your favorite?", help="Select your **favorite** widgets")
-```
-
-
-
-
-
-
-#### Selectbox column
-
-Configure a selectbox column.
-
-```python
-SelectboxColumn("App Category", options=["🤖 LLM", "📈 Data Viz"])
-```
-
-
-
-
-
-
-#### Datetime column
-
-Configure a datetime column.
-
-```python
-DatetimeColumn("Appointment", min_value=datetime(2023, 6, 1), format="D MMM YYYY, h:mm a")
-```
-
-
-
-
-
-
-#### Date column
-
-Configure a date column.
-
-```python
-DateColumn("Birthday", max_value=date(2005, 1, 1), format="DD.MM.YYYY")
-```
-
-
-
-
-
-
-#### Time column
-
-Configure a time column.
-
-```python
-TimeColumn("Appointment", min_value=time(8, 0, 0), format="hh:mm a")
-```
-
-
-
-
-
-#### List column
-
-Configure a list column.
-
-```python
-ListColumn("Sales (last 6 months)", width="medium")
-```
-
-
-
-
-
-
-#### Link column
-
-Configure a link column.
-
-```python
-LinkColumn("Trending apps", max_chars=100, validate="^https://.*$")
-```
-
-
-
-
-
-
-#### Image column
-
-Configure an image column.
-
-```python
-ImageColumn("Preview Image", help="The preview screenshots")
-```
-
-
-
-
-
-
-#### Line chart column
-
-Configure a line chart column.
-
-```python
-LineChartColumn("Sales (last 6 months)" y_min=0, y_max=100)
-```
-
-
-
-
-
-
-#### Bar chart column
-
-Configure a bar chart column.
-
-```python
-BarChartColumn("Marketing spend" y_min=0, y_max=100)
-```
-
-
-
-
-
-
-#### Progress column
-
-Configure a progress column.
-
-```python
-ProgressColumn("Sales volume", min_value=0, max_value=1000, format="$%f")
-```
-
-
-
-
diff --git a/data/library/api/data/column_config/linechartcolumn.md b/data/library/api/data/column_config/linechartcolumn.md
deleted file mode 100644
index 3215f4c95..000000000
--- a/data/library/api/data/column_config/linechartcolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.LineChartColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.linechartcolumn
----
-
-
diff --git a/data/library/api/data/column_config/linkcolumn.md b/data/library/api/data/column_config/linkcolumn.md
deleted file mode 100644
index 05636b024..000000000
--- a/data/library/api/data/column_config/linkcolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.LinkColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.linkcolumn
----
-
-
diff --git a/data/library/api/data/column_config/listcolumn.md b/data/library/api/data/column_config/listcolumn.md
deleted file mode 100644
index f36fd65be..000000000
--- a/data/library/api/data/column_config/listcolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.ListColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.listcolumn
----
-
-
diff --git a/data/library/api/data/column_config/numbercolumn.md b/data/library/api/data/column_config/numbercolumn.md
deleted file mode 100644
index 084eab06f..000000000
--- a/data/library/api/data/column_config/numbercolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.NumberColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.numbercolumn
----
-
-
diff --git a/data/library/api/data/column_config/progresscolumn.md b/data/library/api/data/column_config/progresscolumn.md
deleted file mode 100644
index 9a13473da..000000000
--- a/data/library/api/data/column_config/progresscolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.ProgressColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.progresscolumn
----
-
-
diff --git a/data/library/api/data/column_config/selectboxcolumn.md b/data/library/api/data/column_config/selectboxcolumn.md
deleted file mode 100644
index 6621bfaed..000000000
--- a/data/library/api/data/column_config/selectboxcolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.SelectboxColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.selectboxcolumn
----
-
-
diff --git a/data/library/api/data/column_config/textcolumn.md b/data/library/api/data/column_config/textcolumn.md
deleted file mode 100644
index 5701193bb..000000000
--- a/data/library/api/data/column_config/textcolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.TextColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.textcolumn
----
-
-
diff --git a/data/library/api/data/column_config/timecolumn.md b/data/library/api/data/column_config/timecolumn.md
deleted file mode 100644
index 841d19eb3..000000000
--- a/data/library/api/data/column_config/timecolumn.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: st.column_config.TimeColumn
-slug: /library/api-reference/data/st.column_config/st.column_config.timecolumn
----
-
-
diff --git a/data/library/api/data/data.md b/data/library/api/data/data.md
deleted file mode 100644
index 0731e4e44..000000000
--- a/data/library/api/data/data.md
+++ /dev/null
@@ -1,197 +0,0 @@
----
-title: Data elements
-slug: /library/api-reference/data
----
-
-# Data elements
-
-When you're working with data, it is extremely valuable to visualize that
-data quickly, interactively, and from multiple different angles. That's what
-Streamlit is actually built and optimized for.
-
-You can display data via [charts](#display-charts), and you can display it in
-raw form. These are the Streamlit commands you can use to display and interact with raw data.
-
-
-
-
-
-#### Dataframes
-
-Display a dataframe as an interactive table.
-
-```python
-st.dataframe(my_data_frame)
-```
-
-
-
-
-
-
-#### Data editor
-
-Display a data editor widget.
-
-```python
-edited = st.data_editor(df, num_rows="dynamic")
-```
-
-
-
-
-
-
-#### Column configuration
-
-Configure the display and editing behavior of dataframes and data editors.
-
-```python
-st.column_config.NumberColumn("Price (in USD)", min_value=0, format="$%d")
-```
-
-
-
-
-
-
-#### Static tables
-
-Display a static table.
-
-```python
-st.table(my_data_frame)
-```
-
-
-
-
-
-#### Metrics
-
-Display a metric in big bold font, with an optional indicator of how the metric changed.
-
-```python
-st.metric("My metric", 42, 2)
-```
-
-
-
-
-
-#### Dicts and JSON
-
-Display object or string as a pretty-printed JSON string.
-
-```python
-st.json(my_dict)
-```
-
-
-
-
-
-
-
-
-
-
-#### Streamlit Aggrid
-
-Implementation of Ag-Grid component for Streamlit. Created by [@PablocFonseca](https://github.com/PablocFonseca).
-
-```python
-df = pd.DataFrame({'col1': [1, 2, 3], 'col2': [4, 5, 6]})
-grid_return = AgGrid(df, editable=True)
-
-new_df = grid_return['data']
-```
-
-
-
-
-
-
-
-#### Streamlit Folium
-
-Streamlit Component for rendering Folium maps. Created by [@randyzwitch](https://github.com/randyzwitch).
-
-```python
-m = folium.Map(location=[39.949610, -75.150282], zoom_start=16)
-folium.Marker([39.949610, -75.150282], popup="Liberty Bell", tooltip="Liberty Bell").add_to(m)
-
-st_data = st_folium(m, width=725)
-```
-
-
-
-
-
-
-
-#### Pandas Profiling
-
-Pandas profiling component for Streamlit. Created by [@okld](https://github.com/okld/).
-
-```python
-df = pd.read_csv("https://storage.googleapis.com/tf-datasets/titanic/train.csv")
-pr = df.profile_report()
-
-st_profile_report(pr)
-```
-
-
-
-
-
-
-
-#### Image Coordinates
-
-Get the coordinates of clicks on an image. Created by [@blackary](https://github.com/blackary/).
-
-```python
-from streamlit_image_coordinates import streamlit_image_coordinates
-value = streamlit_image_coordinates("https://placekitten.com/200/300")
-
-st.write(value)
-```
-
-
-
-
-
-
-
-#### Plotly Events
-
-Make Plotly charts interactive!. Created by [@null-jones](https://github.com/null-jones/).
-
-```python
-from streamlit_plotly_events import plotly_events
-fig = px.line(x=[1], y=[1])
-
-selected_points = plotly_events(fig)
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-from streamlit_extras.metric_cards import style_metric_cards
-col3.metric(label="No Change", value=5000, delta=0)
-
-style_metric_cards()
-```
-
-
-
-
diff --git a/data/library/api/data/data_editor.md b/data/library/api/data/data_editor.md
deleted file mode 100644
index ff165ecbc..000000000
--- a/data/library/api/data/data_editor.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: st.data_editor
-slug: /library/api-reference/data/st.data_editor
-description: st.data_editor display a data editor widget that allows you to edit dataframes and many other data structures in a table-like UI.
----
-
-
-
-This page only contains information on the `st.data_editor` API. For an overview of working with dataframes and to learn more about the data editor's capabilities and limitations, read [Dataframes](/library/advanced-features/dataframes).
-
-
-
-
-
-### Configuring columns
-
-You can configure the display and editing behavior of columns in `st.dataframe` and `st.data_editor` via the [Column configuration API](/library/api-reference/data/st.column_config). We have developed the API to let you add images, charts, and clickable URLs in dataframe and data editor columns. Additionally, you can make individual columns editable, set columns as categorical and specify which options they can take, hide the index of the dataframe, and much more.
-
-
diff --git a/data/library/api/data/dataframe.md b/data/library/api/data/dataframe.md
deleted file mode 100644
index 9da3690a0..000000000
--- a/data/library/api/data/dataframe.md
+++ /dev/null
@@ -1,53 +0,0 @@
----
-title: st.dataframe
-slug: /library/api-reference/data/st.dataframe
-description: st.dataframe displays a dataframe as an interactive table.
----
-
-
-
-This page only contains information on the `st.dataframe` API. For an overview of working with dataframes read [Dataframes](/library/advanced-features/dataframes). If you want to let users interactively edit dataframes, check out [`st.data_editor`](/library/api-reference/data/st.data_editor).
-
-
-
-
-
-
-
-`st.dataframe` supports the `use_container_width` parameter to stretch across the full container width:
-
-```python
-import pandas as pd
-import streamlit as st
-
-# Cache the dataframe so it's only loaded once
-@st.cache_data
-def load_data():
- return pd.DataFrame(
- {
- "first column": [1, 2, 3, 4],
- "second column": [10, 20, 30, 40],
- }
- )
-
-# Boolean to resize the dataframe, stored as a session state variable
-st.checkbox("Use container width", value=False, key="use_container_width")
-
-df = load_data()
-
-# Display the dataframe and allow the user to stretch the dataframe
-# across the full width of the container, based on the checkbox value
-st.dataframe(df, use_container_width=st.session_state.use_container_width)
-```
-
-
-
-### Interactivity
-
-Dataframes displayed with `st.dataframe` are interactive. End users can sort, resize, search, and copy data to their clipboard. For on overview of features, read our [Dataframes](/library/advanced-features/dataframes#additional-ui-features) guide.
-
-### Configuring columns
-
-You can configure the display and editing behavior of columns in `st.dataframe` and `st.data_editor` via the [Column configuration API](/library/api-reference/data/st.column_config). We have developed the API to let you add images, charts, and clickable URLs in dataframe and data editor columns. Additionally, you can make individual columns editable, set columns as categorical and specify which options they can take, hide the index of the dataframe, and much more.
-
-
diff --git a/data/library/api/data/json.md b/data/library/api/data/json.md
deleted file mode 100644
index a93906cc0..000000000
--- a/data/library/api/data/json.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.json
-slug: /library/api-reference/data/st.json
-description: st.json displays object or string as a pretty-printed JSON string.
----
-
-
diff --git a/data/library/api/data/metric.md b/data/library/api/data/metric.md
deleted file mode 100644
index a0459246b..000000000
--- a/data/library/api/data/metric.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.metric
-slug: /library/api-reference/data/st.metric
-description: st.metric displays a metric in big bold font, with an optional indicator of how the metric changed.
----
-
-
diff --git a/data/library/api/data/table.md b/data/library/api/data/table.md
deleted file mode 100644
index 8ca3cf2ac..000000000
--- a/data/library/api/data/table.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: st.table
-slug: /library/api-reference/data/st.table
-description: st.table displays a static table.
----
-
-
-
-Static tables with `st.table` are the most basic way to display dataframes. For the majority of cases, we recommend using [`st.dataframe`](/library/api-reference/data/st.dataframe) to display interactive dataframes, and [`st.data_editor`](/library/api-reference/data/st.data_editor) to let users edit dataframes.
-
-
-
-
diff --git a/data/library/api/layout/columns.md b/data/library/api/layout/columns.md
deleted file mode 100644
index 33fd16228..000000000
--- a/data/library/api/layout/columns.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.columns
-slug: /library/api-reference/layout/st.columns
-description: st.columns inserts containers laid out as side-by-side columns.
----
-
-
diff --git a/data/library/api/layout/container.md b/data/library/api/layout/container.md
deleted file mode 100644
index 7cc591cc6..000000000
--- a/data/library/api/layout/container.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.container
-slug: /library/api-reference/layout/st.container
-description: st.container inserts a multi-element container.
----
-
-
diff --git a/data/library/api/layout/empty.md b/data/library/api/layout/empty.md
deleted file mode 100644
index 236ece083..000000000
--- a/data/library/api/layout/empty.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.empty
-slug: /library/api-reference/layout/st.empty
-description: st.empty inserts a single-element container.
----
-
-
diff --git a/data/library/api/layout/expander.md b/data/library/api/layout/expander.md
deleted file mode 100644
index a64bbf28c..000000000
--- a/data/library/api/layout/expander.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.expander
-slug: /library/api-reference/layout/st.expander
-description: st.expander inserts a multi-element container that can be expanded/collapsed.
----
-
-
diff --git a/data/library/api/layout/layout.md b/data/library/api/layout/layout.md
deleted file mode 100644
index c00a1a342..000000000
--- a/data/library/api/layout/layout.md
+++ /dev/null
@@ -1,158 +0,0 @@
----
-title: Layouts and Containers
-slug: /library/api-reference/layout
----
-
-# Layouts and Containers
-
-## Complex layouts
-
-Streamlit provides several options for controlling how different elements are laid out on the screen.
-
-
-
-
-
-
-#### Sidebar
-
-Display items in a sidebar.
-
-```python
-st.sidebar.write("This lives in the sidebar")
-st.sidebar.button("Click me!")
-```
-
-
-
-
-
-
-#### Columns
-
-Insert containers laid out as side-by-side columns.
-
-```python
-col1, col2 = st.columns(2)
-col1.write("this is column 1")
-col2.write("this is column 2")
-```
-
-
-
-
-
-
-#### Tabs
-
-Insert containers separated into tabs.
-
-```python
-tab1, tab2 = st.tabs(["Tab 1", "Tab2"])
-tab1.write("this is tab 1")
-tab2.write("this is tab 2")
-```
-
-
-
-
-
-
-#### Expander
-
-Insert a multi-element container that can be expanded/collapsed.
-
-```python
-with st.expander("Open to see more"):
- st.write("This is more content")
-```
-
-
-
-
-
-
-#### Container
-
-Insert a multi-element container.
-
-```python
-c = st.container()
-st.write("This will show last")
-c.write("This will show first")
-c.write("This will show second")
-```
-
-
-
-
-
-
-#### Empty
-
-Insert a single-element container.
-
-```python
-c = st.empty()
-st.write("This will show last")
-c.write("This will be replaced")
-c.write("This will show first")
-```
-
-
-
-
-
-
-
-
-
-
-#### Streamlit Elements
-
-Create a draggable and resizable dashboard in Streamlit. Created by [@okls](https://github.com/okls).
-
-```python
-from streamlit_elements import elements, mui, html
-
-with elements("new_element"):
- mui.Typography("Hello world")
-```
-
-
-
-
-
-
-
-#### Pydantic
-
-Auto-generate Streamlit UI from Pydantic Models and Dataclasses. Created by [@lukasmasuch](https://github.com/lukasmasuch).
-
-```python
-import streamlit_pydantic as sp
-
-sp.pydantic_form(key="my_form",
- model=ExampleModel)
-```
-
-
-
-
-
-
-
-#### Streamlit Pages
-
-An experimental version of Streamlit Multi-Page Apps. Created by [@blackary](https://github.com/blackary).
-
-```python
-from st_pages import Page, show_pages, add_page_title
-
-show_pages([ Page("streamlit_app.py", "Home", "🏠"),
- Page("other_pages/page2.py", "Page 2", ":books:"), ])
-```
-
-
-
-
diff --git a/data/library/api/layout/sidebar.md b/data/library/api/layout/sidebar.md
deleted file mode 100644
index cddf36616..000000000
--- a/data/library/api/layout/sidebar.md
+++ /dev/null
@@ -1,71 +0,0 @@
----
-title: st.sidebar
-slug: /library/api-reference/layout/st.sidebar
-description: st.sidebar displays items in a sidebar.
----
-
-## st.sidebar
-
-## Add widgets to sidebar
-
-Not only can you add interactivity to your app with widgets, you can organize them into a sidebar. Elements can be passed to `st.sidebar` using object notation and `with` notation.
-
-The following two snippets are equivalent:
-
-```python
-# Object notation
-st.sidebar.[element_name]
-```
-
-```python
-# "with" notation
-with st.sidebar:
- st.[element_name]
-```
-
-Each element that's passed to `st.sidebar` is pinned to the left, allowing users to focus on the content in your app.
-
-
-
-The sidebar is resizable! Drag and drop the right border of the sidebar to resize it! ↔️
-
-
-
-Here's an example of how you'd add a selectbox and a radio button to your sidebar:
-
-```python
-import streamlit as st
-
-# Using object notation
-add_selectbox = st.sidebar.selectbox(
- "How would you like to be contacted?",
- ("Email", "Home phone", "Mobile phone")
-)
-
-# Using "with" notation
-with st.sidebar:
- add_radio = st.radio(
- "Choose a shipping method",
- ("Standard (5-15 days)", "Express (2-5 days)")
- )
-```
-
-
-
-The only elements that aren't supported using object notation are `st.echo`, `st.spinner`, and `st.toast`. To use these elements, you must use `with` notation.
-
-
-
-Here's an example of how you'd add [`st.echo`](/library/api-reference/utilities/st.echo) and [`st.spinner`](/library/api-reference/status/st.spinner) to your sidebar:
-
-```python
-import streamlit as st
-
-with st.sidebar:
- with st.echo():
- st.write("This code will be printed to the sidebar.")
-
- with st.spinner("Loading..."):
- time.sleep(5)
- st.success("Done!")
-```
diff --git a/data/library/api/layout/tabs.md b/data/library/api/layout/tabs.md
deleted file mode 100644
index c2114fa12..000000000
--- a/data/library/api/layout/tabs.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.tabs
-slug: /library/api-reference/layout/st.tabs
-description: st.tabs inserts containers separated into tabs.
----
-
-
diff --git a/data/library/api/media/audio.md b/data/library/api/media/audio.md
deleted file mode 100644
index 838868439..000000000
--- a/data/library/api/media/audio.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.audio
-slug: /library/api-reference/media/st.audio
-description: st.audio displays an audio player.
----
-
-
diff --git a/data/library/api/media/image.md b/data/library/api/media/image.md
deleted file mode 100644
index 1ea25ba68..000000000
--- a/data/library/api/media/image.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.image
-slug: /library/api-reference/media/st.image
-description: st.image displays an image or list of images.
----
-
-
diff --git a/data/library/api/media/media.md b/data/library/api/media/media.md
deleted file mode 100644
index cfb2193a0..000000000
--- a/data/library/api/media/media.md
+++ /dev/null
@@ -1,159 +0,0 @@
----
-title: Media elements
-slug: /library/api-reference/media
----
-
-# Media elements
-
-It's easy to embed images, videos, and audio files directly into your Streamlit apps.
-
-
-
-
-
-
-#### Image
-
-Display an image or list of images.
-
-```python
-st.image(numpy_array)
-st.image(image_bytes)
-st.image(file)
-st.image("https://example.com/myimage.jpg")
-```
-
-
-
-
-
-
-#### Audio
-
-Display an audio player.
-
-```python
-st.audio(numpy_array)
-st.audio(audio_bytes)
-st.audio(file)
-st.audio("https://example.com/myaudio.mp3", format="audio/mp3")
-```
-
-
-
-
-
-
-#### Video
-
-Display a video player.
-
-```python
-st.video(numpy_array)
-st.video(video_bytes)
-st.video(file)
-st.video("https://example.com/myvideo.mp4", format="video/mp4")
-```
-
-
-
-
-
-
-
-
-
-
-#### Streamlit Webrtc
-
-Handling and transmitting real-time video/audio streams with Streamlit. Created by [@whitphx](https://github.com/whitphx).
-
-```python
-from streamlit_webrtc import webrtc_streamer
-
-webrtc_streamer(key="sample")
-```
-
-
-
-
-
-
-
-#### Drawable Canvas
-
-Provides a sketching canvas using [Fabric.js](http://fabricjs.com/). Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-from streamlit_drawable_canvas import st_canvas
-
-st_canvas(fill_color="rgba(255, 165, 0, 0.3)", stroke_width=stroke_width, stroke_color=stroke_color, background_color=bg_color, background_image=Image.open(bg_image) if bg_image else None, update_streamlit=realtime_update, height=150, drawing_mode=drawing_mode, point_display_radius=point_display_radius if drawing_mode == 'point' else 0, key="canvas",)
-```
-
-
-
-
-
-
-
-#### Image Comparison
-
-Compare images with a slider using [JuxtaposeJS](https://juxtapose.knightlab.com/). Created by [@fcakyon](https://github.com/fcakyon).
-
-```python
-from streamlit_image_comparison import image_comparison
-
-image_comparison(img1="image1.jpg", img2="image2.jpg",)
-```
-
-
-
-
-
-
-
-#### Streamlit Cropper
-
-A simple image cropper for Streamlit. Created by [@turner-anderson](https://github.com/turner-anderson).
-
-```python
-from streamlit_cropper import st_cropper
-
-st_cropper(img, realtime_update=realtime_update, box_color=box_color, aspect_ratio=aspect_ratio)
-```
-
-
-
-
-
-
-
-#### Image Coordinates
-
-Get the coordinates of clicks on an image. Created by [@blackary](https://github.com/blackary/).
-
-```python
-from streamlit_image_coordinates import streamlit_image_coordinates
-
-streamlit_image_coordinates("https://placekitten.com/200/300")
-```
-
-
-
-
-
-
-
-#### Streamlit Lottie
-
-Integrate [Lottie](https://lottiefiles.com/) animations inside your Streamlit app. Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-lottie_hello = load_lottieurl("https://assets5.lottiefiles.com/packages/lf20_V9t630.json")
-
-st_lottie(lottie_hello, key="hello")
-```
-
-
-
-
diff --git a/data/library/api/media/video.md b/data/library/api/media/video.md
deleted file mode 100644
index 054894831..000000000
--- a/data/library/api/media/video.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.video
-slug: /library/api-reference/media/st.video
-description: st.video displays a video player.
----
-
-
diff --git a/data/library/api/mutate/mutate.md b/data/library/api/mutate/mutate.md
deleted file mode 100644
index 42d91b0df..000000000
--- a/data/library/api/mutate/mutate.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: Mutate charts
-slug: /library/api-reference/mutate
-description: st.add_rows appends a dataframe to the bottom of the current one in certain elements, for optimized data updates.
----
-
-# Mutate charts
-
-Sometimes you display a chart or dataframe and want to modify live as the app
-runs (for example, in a loop). Depending on what you're looking for, there are 3 different ways to
-do this:
-
-1. Using [`st.empty`](/library/api-reference/layout/st.empty) to replace a single element.
-2. Using [`st.container`](/library/api-reference/layout/st.container) or
- [`st.columns`](/library/api-reference/layout/st.columns) to replace multiple elements.
-3. Using `add_rows` to append data to specific types of elements.
-
-Here we discuss that last case.
-
-
diff --git a/data/library/api/performance/cache-data-clear.md b/data/library/api/performance/cache-data-clear.md
deleted file mode 100644
index c5f8e3090..000000000
--- a/data/library/api/performance/cache-data-clear.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: st.cache_data.clear
-slug: /library/api-reference/performance/st.cache_data.clear
-description: st.cache_data.clear clears all in-memory and on-disk data caches.
----
-
-
-
-#### Example
-
-In the example below, pressing the "Clear All" button will clear memoized values from all functions decorated with `@st.cache_data`.
-
-```python
-import streamlit as st
-
-@st.cache_data
-def square(x):
- return x**2
-
-@st.cache_data
-def cube(x):
- return x**3
-
-if st.button("Clear All"):
- # Clear values from *all* all in-memory and on-disk data caches:
- # i.e. clear values from both square and cube
- st.cache_data.clear()
-```
diff --git a/data/library/api/performance/cache-data.md b/data/library/api/performance/cache-data.md
deleted file mode 100644
index 1df062fbc..000000000
--- a/data/library/api/performance/cache-data.md
+++ /dev/null
@@ -1,68 +0,0 @@
----
-title: st.cache_data
-slug: /library/api-reference/performance/st.cache_data
-description: st.cache_data is used to cache functions that return data (e.g. dataframe transforms, database queries, ML inference).
----
-
-
-
-This page only contains information on the `st.cache_data` API. For a deeper dive into caching and how to use it, check out [Caching](/library/advanced-features/caching).
-
-
-
-
-## Using Streamlit commands in cached functions
-
-### Static elements
-
-Since version 1.16.0, cached functions can contain Streamlit commands! For example, you can do this:
-
-```python
-@st.cache_data
-def get_api_data():
- data = api.get(...)
- st.success("Fetched data from API!") # 👈 Show a success message
- return data
-```
-
-As we know, Streamlit only runs this function if it hasn’t been cached before. On this first run, the `st.success` message will appear in the app. But what happens on subsequent runs? It still shows up! Streamlit realizes that there is an `st.` command inside the cached function, saves it during the first run, and replays it on subsequent runs. Replaying static elements works for both caching decorators.
-
-You can also use this functionality to cache entire parts of your UI:
-
-```python
-@st.cache_data
-def show_data():
- st.header("Data analysis")
- data = api.get(...)
- st.success("Fetched data from API!")
- st.write("Here is a plot of the data:")
- st.line_chart(data)
- st.write("And here is the raw data:")
- st.dataframe(data)
-```
-
-### Input widgets
-
-You can also use [interactive input widgets](/library/api-reference/widgets) like `st.slider` or `st.text_input` in cached functions. Widget replay is an experimental feature at the moment. To enable it, you need to set the `experimental_allow_widgets` parameter:
-
-```python
-@st.cache_data(experimental_allow_widgets=True) # 👈 Set the parameter
-def get_data():
- num_rows = st.slider("Number of rows to get") # 👈 Add a slider
- data = api.get(..., num_rows)
- return data
-```
-
-Streamlit treats the slider like an additional input parameter to the cached function. If you change the slider position, Streamlit will see if it has already cached the function for this slider value. If yes, it will return the cached value. If not, it will rerun the function using the new slider value.
-
-Using widgets in cached functions is extremely powerful because it lets you cache entire parts of your app. But it can be dangerous! Since Streamlit treats the widget value as an additional input parameter, it can easily lead to excessive memory usage. Imagine your cached function has five sliders and returns a 100 MB DataFrame. Then we’ll add 100 MB to the cache for _every permutation_ of these five slider values – even if the sliders do not influence the returned data! These additions can make your cache explode very quickly. Please be aware of this limitation if you use widgets in cached functions. We recommend using this feature only for isolated parts of your UI where the widgets directly influence the cached return value.
-
-
-
-Support for widgets in cached functions is currently experimental. We may change or remove it anytime without warning. Please use it with care!
-
-
-
-
-Two widgets are currently not supported in cached functions: `st.file_uploader` and `st.camera_input`. We may support them in the future. Feel free to [open a GitHub issue](https://github.com/streamlit/streamlit/issues) if you need them!
-
diff --git a/data/library/api/performance/cache-resource-clear.md b/data/library/api/performance/cache-resource-clear.md
deleted file mode 100644
index e5ddd2f7f..000000000
--- a/data/library/api/performance/cache-resource-clear.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: st.cache_resource.clear
-slug: /library/api-reference/performance/st.cache_resource.clear
-description: st.cache_resource.clear clears all cache_resource caches.
----
-
-
-
-#### Example
-
-In the example below, pressing the "Clear All" button will clear _all_ cache_resource caches. i.e. Clears cached global resources from all functions decorated with `@st.cache_resource`.
-
-```python
-import streamlit as st
-from transformers import BertModel
-
-@st.cache_resource
- def get_database_session(url):
- # Create a database session object that points to the URL.
- return session
-
-@st.cache_resource
-def get_model(model_type):
- # Create a model of the specified type.
- return BertModel.from_pretrained(model_type)
-
-if st.button("Clear All"):
- # Clears all st.cache_resource caches:
- st.cache_resource.clear()
-```
diff --git a/data/library/api/performance/cache-resource.md b/data/library/api/performance/cache-resource.md
deleted file mode 100644
index 0849ecd25..000000000
--- a/data/library/api/performance/cache-resource.md
+++ /dev/null
@@ -1,70 +0,0 @@
----
-title: st.cache_resource
-slug: /library/api-reference/performance/st.cache_resource
-description: st.cache_resource is used to cache functions that return shared global resources (e.g. database connections, ML models).
----
-
-
-
-This page only contains information on the `st.cache_resource` API. For a deeper dive into caching and how to use it, check out [Caching](/library/advanced-features/caching).
-
-
-
-
-## Using Streamlit commands in cached functions
-
-### Static elements
-
-Since version 1.16.0, cached functions can contain Streamlit commands! For example, you can do this:
-
-```python
-from transformers import pipeline
-
-@st.cache_resource
-def load_model():
- model = pipeline("sentiment-analysis")
- st.success("Loaded NLP model from Hugging Face!") # 👈 Show a success message
- return model
-```
-
-As we know, Streamlit only runs this function if it hasn’t been cached before. On this first run, the `st.success` message will appear in the app. But what happens on subsequent runs? It still shows up! Streamlit realizes that there is an `st.` command inside the cached function, saves it during the first run, and replays it on subsequent runs. Replaying static elements works for both caching decorators.
-
-You can also use this functionality to cache entire parts of your UI:
-
-```python
-@st.cache_resource
-def load_model():
- st.header("Data analysis")
- model = torchvision.models.resnet50(weights=ResNet50_Weights.DEFAULT)
- st.success("Loaded model!")
- st.write("Turning on evaluation mode...")
- model.eval()
- st.write("Here's the model:")
- return model
-```
-
-### Input widgets
-
-You can also use [interactive input widgets](/library/api-reference/widgets) like `st.slider` or `st.text_input` in cached functions. Widget replay is an experimental feature at the moment. To enable it, you need to set the `experimental_allow_widgets` parameter:
-
-```python
-@st.cache_data(experimental_allow_widgets=True) # 👈 Set the parameter
-def load_model():
- pretrained = st.checkbox("Use pre-trained model:") # 👈 Add a checkbox
- model = torchvision.models.resnet50(weights=ResNet50_Weights.DEFAULT, pretrained=pretrained)
- return model
-```
-
-Streamlit treats the checkbox like an additional input parameter to the cached function. If you uncheck it, Streamlit will see if it has already cached the function for this checkbox state. If yes, it will return the cached value. If not, it will rerun the function using the new slider value.
-
-Using widgets in cached functions is extremely powerful because it lets you cache entire parts of your app. But it can be dangerous! Since Streamlit treats the widget value as an additional input parameter, it can easily lead to excessive memory usage. Imagine your cached function has five sliders and returns a 100 MB DataFrame. Then we’ll add 100 MB to the cache for _every permutation_ of these five slider values – even if the sliders do not influence the returned data! These additions can make your cache explode very quickly. Please be aware of this limitation if you use widgets in cached functions. We recommend using this feature only for isolated parts of your UI where the widgets directly influence the cached return value.
-
-
-
-Support for widgets in cached functions is currently experimental. We may change or remove it anytime without warning. Please use it with care!
-
-
-
-
-Two widgets are currently not supported in cached functions: `st.file_uploader` and `st.camera_input`. We may support them in the future. Feel free to [open a GitHub issue](https://github.com/streamlit/streamlit/issues) if you need them!
-
diff --git a/data/library/api/performance/performance.md b/data/library/api/performance/performance.md
deleted file mode 100644
index 237e17651..000000000
--- a/data/library/api/performance/performance.md
+++ /dev/null
@@ -1,93 +0,0 @@
----
-title: Optimize performance
-slug: /library/api-reference/performance
----
-
-# Optimize performance
-
-Streamlit provides powerful [cache primitives](/library/advanced-features/caching) for data and global resources. They allow your app to stay performant even when loading data from the web, manipulating large datasets, or performing expensive computations.
-
-
-
-
-
-#### Cache data
-
-Function decorator to cache functions that return data (e.g. dataframe transforms, database queries, ML inference).
-
-```python
-@st.cache_data
-def long_function(param1, param2):
- # Perform expensive computation here or
- # fetch data from the web here
- return data
-```
-
-
-
-
-
-#### Cache resource
-
-Function decorator to cache functions that return global resources (e.g. database connections, ML models).
-
-```python
-@st.cache_resource
-def init_model():
- # Return a global resource here
- return pipeline(
- "sentiment-analysis",
- model="distilbert-base-uncased-finetuned-sst-2-english"
- )
-```
-
-
-
-
-
-#### Clear cached data
-
-Clear all in-memory and on-disk data caches.
-
-```python
-@st.cache_data
-def long_function(param1, param2):
- # Perform expensive computation here or
- # fetch data from the web here
- return data
-
-if st.checkbox("Clear All"):
- # Clear values from *all* cache_data functions
- st.cache_data.clear()
-```
-
-
-
-
-
-#### Clear cached resources
-
-Clear all `st.cache_resource` caches.
-
-```python
-@st.cache_resource
-def init_model():
- # Return a global resource here
- return pipeline(
- "sentiment-analysis",
- model="distilbert-base-uncased-finetuned-sst-2-english"
- )
-
-if st.checkbox("Clear All"):
- # Clear values from *all* cache_resource functions
- st.cache_data.clear()
-```
-
-
-
-
-
-
-
-All the below commands were deprecated in version 1.18.0. Use the new commands above instead. Learn more in [Caching](/library/advanced-features/caching).
-
diff --git a/data/library/api/personalization/experimental-user.md b/data/library/api/personalization/experimental-user.md
deleted file mode 100644
index 56c936049..000000000
--- a/data/library/api/personalization/experimental-user.md
+++ /dev/null
@@ -1,170 +0,0 @@
----
-title: st.experimental_user
-slug: /library/api-reference/personalization/st.experimental_user
-description: st.experimental_user returns information about the logged-in user of private apps on Streamlit Community Cloud.
----
-
-# st.experimental_user
-
-
-
-This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
-
-
-
-`st.experimental_user` is a Streamlit command that returns information about the logged-in user on Streamlit Community Cloud. It allows developers to personalize apps for the user viewing the app. In a private Streamlit Community Cloud app, it returns a dictionary with the viewer's email. This value of this field is empty in a public Streamlit Community Cloud app to prevent leaking user emails to developers.
-
-The API closely resembles that of [`st.session_state`](/library/api-reference/session-state) and [`st.secrets`](/streamlit-community-cloud/deploy-your-app/secrets-management). It follows a field-based API, which is very similar to Python dictionaries.
-
-### Allowed fields
-
-The `st.experimental_user` command returns a dictionary with only one field: `email`.
-
-Display the allowed field by passing the command to `st.write`:
-
-```python
-# Display the contents of the dictionary
-st.write(st.experimental_user)
-```
-
-The above displays a dict with one field and value. The field is always `email`:
-
-```json
-{
- "email": "value"
-}
-```
-
-You can check if a field exists in `st.experimental_user`:
-
-```python
-# Returns True if the field exists
-"email" in st.experimental_user
-
-# Returns False if the field does not exist
-"name" in st.experimental_user
-```
-
-### Read values
-
-Read the value of the `email` field and display it by passing to `st.write`:
-
-```python
-# Dictionary like API
-st.write(st.experimental_user['email'])
-
-# Attribute API
-st.write(st.experimental_user.email)
-```
-
-The above outputs either `None` or the logged-in user's email or test@localhost.com, depending on where the app is running. Read further to learn about `st.experimental_user`'s context-dependent behavior.
-
-### Updates and modifications
-
-Keys and values for `st.experimental_user` **cannot** be updated or modified. Streamlit throws a handy `StreamlitAPIException` exception if you try to update them:
-
-```python
-st.experimental_user.name = None
-# Throws an exception!
-
-st.experimental_user.email = "hello"
-# Throws an exception!
-```
-
-
-
-### Context-dependent behavior
-
-The value of `st.experimental_user.email` is context-dependent. It returns a value depending on where the app is running. The [private](#private-app-on-streamlit-cloud) or [public](#public-app-on-streamlit-cloud) app can be running on Streamlit Community Cloud, [locally](#local-development), or on a [3rd party cloud provider](#app-deployed-on-a-3rd-party-cloud-provider). Let's look at the different scenarios.
-
-#### **Private app on Streamlit Community Cloud**
-
-Users need to be logged in to Streamlit Community Cloud to view private apps. If a user is not logged, they see:
-
-
-
-
-
-If a user is logged in, `st.experimental_user.email` returns the user's email. Suppose a user logged in to Streamlit Community Cloud using jane@email.com:
-
-```python
-st.experimental_user.email
-# Returns: jane@email.com
-```
-
-#### **Public app on Streamlit Community Cloud**
-
-Currently, `st.experimental_user.email` returns information about the logged-in user of _private apps_ on Streamlit Community Cloud. If used in a public app, it returns `None`. For example:
-
-```python
-st.experimental_user.email
-# Returns: None
-```
-
-This value of this field is empty in a public Streamlit Community Cloud app to prevent leaking user emails to developers.
-
-#### **Local development**
-
-When developing locally, `st.experimental_user.email` returns test@localhost.com. We don't return `None` to make it easier to locally test this functionality. For example:
-
-```python
-st.experimental_user.email
-# Returns: test@localhost.com
-```
-
-#### **App deployed on a 3rd party cloud provider**
-
-When deploying an app on a 3rd party cloud provider (e.g. Amazon EC2, Heroku, etc), `st.experimental_user.email` behaves the same as during local development. For example:
-
-```python
-st.experimental_user.email # On a 3rd party cloud provider
-# Returns: test@localhost.com
-```
-
-### Examples
-
-The ability to personalize apps for the user viewing the app is a great way to make your app more engaging.
-
-It unlocks a plethora of use-cases for developers, some of which could include: showing additional controls for admins, visualizing a user's Streamlit history, a personalized stock ticker, a chatbot app, and much more. We're excited to see what you build with this feature!
-
-Here's a code snippet that shows extra buttons for admins:
-
-```python
-# Show extra buttons for admin users.
-ADMIN_USERS = {
- 'person1@email.com',
- 'person2@email.com',
- 'person3@email.com'
-}
-if st.experimental_user.email in ADMIN_USERS:
- display_the_extra_admin_buttons()
-display_the_interface_everyone_sees()
-```
-
-Show different content to users based on their email address:
-
-```python
-# Show different content based on the user's email address.
-if st.experimental_user.email == 'jane@email.com':
- display_jane_content()
-elif st.experimental_user.email == 'adam@foocorp.io':
- display_adam_content()
-else:
- st.write("Please contact us to get access!")
-```
-
-Greet users with their name that's stored in a database:
-
-```python
-# Greet the user by their name.
-if st.experimental_user.email:
- # Get the user's name from the database.
- name = get_name_from_db(st.experimental_user.email)
- st.write('Hello, %s!' % name)
-```
-
-### Caveats and limitations
-
-- `st.experimental_user` is **read-only**. You cannot update or modify its value. Doing so will throw a `StreamlitAPIException`.
-- A valid email is returned only if the user is logged in to Streamlit Community Cloud and the app is private. Else, `None` or test@localhost.com is returned.
-- This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
diff --git a/data/library/api/personalization/personalization.md b/data/library/api/personalization/personalization.md
deleted file mode 100644
index 631bd9e17..000000000
--- a/data/library/api/personalization/personalization.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: Personalize apps for the user
-slug: /library/api-reference/personalization
----
-
-# Personalize apps for the user
-
-
-
-
-#### User info
-
-`st.experimental_user` returns information about the logged-in user of private apps on Streamlit Community Cloud.
-
-```python
-if st.experimental_user.email == "foo@corp.com":
- st.write("Welcome back, ", st.experimental_user.email)
-else:
- st.write("You are not authorized to view this page.")
-```
-
-
-
diff --git a/data/library/api/state/state.md b/data/library/api/state/state.md
deleted file mode 100644
index 0895daf43..000000000
--- a/data/library/api/state/state.md
+++ /dev/null
@@ -1,188 +0,0 @@
----
-title: Session State
-slug: /library/api-reference/session-state
-description: st.session_state is a way to share variables between reruns, for each user session.
----
-
-# Session State
-
-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. Session state also persists across apps inside a [multipage app](/library/get-started/multipage-apps).
-
-Check out this Session State basics tutorial video by Streamlit Developer Advocate Dr. Marisa Smith to get started:
-
-
-
-### Initialize values in Session State
-
-The Session State API follows a field-based API, which is very similar to Python dictionaries:
-
-```python
-# Initialization
-if 'key' not in st.session_state:
- st.session_state['key'] = 'value'
-
-# Session State also supports attribute based syntax
-if 'key' not in st.session_state:
- st.session_state.key = 'value'
-```
-
-### Reads and updates
-
-Read the value of an item in Session State and display it by passing to `st.write` :
-
-```python
-# Read
-st.write(st.session_state.key)
-
-# Outputs: value
-```
-
-Update an item in Session State by assigning it a value:
-
-```python
-st.session_state.key = 'value2' # Attribute API
-st.session_state['key'] = 'value2' # Dictionary like API
-```
-
-Curious about what is in Session State? Use `st.write` or magic:
-
-```python
-st.write(st.session_state)
-
-# With magic:
-st.session_state
-```
-
-Streamlit throws a handy exception if an uninitialized variable is accessed:
-
-```python
-st.write(st.session_state['value'])
-
-# Throws an exception!
-```
-
-
-
-### Delete items
-
-Delete items in Session State using the syntax to delete items in any Python dictionary:
-
-```python
-# Delete a single key-value pair
-del st.session_state[key]
-
-# Delete all the items in Session state
-for key in st.session_state.keys():
- del st.session_state[key]
-```
-
-Session State can also be cleared by going to Settings → Clear Cache, followed by Rerunning the app.
-
-
-
-### Session State and Widget State association
-
-Every widget with a key is automatically added to Session State:
-
-```python
-st.text_input("Your name", key="name")
-
-# This exists now:
-st.session_state.name
-```
-
-### Use Callbacks to update Session State
-
-A callback is a python function which gets called when an input widget changes.
-
-**Order of execution**: When updating Session state in response to **events**, a callback function gets executed first, and then the app is executed from top to bottom.
-
-Callbacks can be used with widgets using the parameters `on_change` (or `on_click`), `args`, and `kwargs`:
-
-**Parameters**
-
-- **on_change** or **on_click** - The function name to be used as a callback
-- **args** (_tuple_) - List of arguments to be passed to the callback function
-- **kwargs** (_dict_) - Named arguments to be passed to the callback function
-
-Widgets which support the `on_change` event:
-
-- `st.checkbox`
-- `st.color_picker`
-- `st.date_input`
-- `st.multiselect`
-- `st.number_input`
-- `st.radio`
-- `st.select_slider`
-- `st.selectbox`
-- `st.slider`
-- `st.text_area`
-- `st.text_input`
-- `st.time_input`
-- `st.file_uploader`
-
-Widgets which support the `on_click` event:
-
-- `st.button`
-- `st.download_button`
-- `st.form_submit_button`
-
-To add a callback, define a callback function **above** the widget declaration and pass it to the widget via the `on_change` (or `on_click` ) parameter.
-
-### Forms and Callbacks
-
-Widgets inside a form can have their values be accessed and set via the Session State API. `st.form_submit_button` can have a callback associated with it. The callback gets executed upon clicking on the submit button. For example:
-
-```python
-def form_callback():
- st.write(st.session_state.my_slider)
- st.write(st.session_state.my_checkbox)
-
-with st.form(key='my_form'):
- slider_input = st.slider('My slider', 0, 10, 5, key='my_slider')
- checkbox_input = st.checkbox('Yes or No', key='my_checkbox')
- submit_button = st.form_submit_button(label='Submit', on_click=form_callback)
-```
-
-### Caveats and limitations
-
-- Only the `st.form_submit_button` has a callback in forms. Other widgets inside a form are not allowed to have callbacks.
-- `on_change` and `on_click` events are only supported on input type widgets.
-- Modifying the value of a widget via the Session state API, after instantiating it, is not allowed and will raise a `StreamlitAPIException`. For example:
-
- ```python
- slider = st.slider(
- label='My Slider', min_value=1,
- max_value=10, value=5, key='my_slider')
-
- st.session_state.my_slider = 7
-
- # Throws an exception!
- ```
-
- 
-
-- Setting the widget state via the Session State API and using the `value` parameter in the widget declaration is not recommended, and will throw a warning on the first run. For example:
-
- ```python
- st.session_state.my_slider = 7
-
- slider = st.slider(
- label='Choose a Value', min_value=1,
- max_value=10, value=5, key='my_slider')
- ```
-
- 
-
-- Setting the state of button-like widgets: `st.button`, `st.download_button`, and `st.file_uploader` via the Session State API is not allowed. Such type of widgets are by default _False_ and have ephemeral _True_ states which are only valid for a single run. For example:
-
- ```python
- if 'my_button' not in st.session_state:
- st.session_state.my_button = True
-
- st.button('My button', key='my_button')
-
- # Throws an exception!
- ```
-
- 
diff --git a/data/library/api/status/balloons.md b/data/library/api/status/balloons.md
deleted file mode 100644
index 39e1d3cea..000000000
--- a/data/library/api/status/balloons.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.balloons
-slug: /library/api-reference/status/st.balloons
-description: st.balloons displays celebratory balloons!
----
-
-
diff --git a/data/library/api/status/error.md b/data/library/api/status/error.md
deleted file mode 100644
index 9dc8f6462..000000000
--- a/data/library/api/status/error.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.error
-slug: /library/api-reference/status/st.error
-description: st.error displays error message.
----
-
-
diff --git a/data/library/api/status/exception.md b/data/library/api/status/exception.md
deleted file mode 100644
index a05470bb1..000000000
--- a/data/library/api/status/exception.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.exception
-slug: /library/api-reference/status/st.exception
-description: st.exception displays an exception.
----
-
-
diff --git a/data/library/api/status/info.md b/data/library/api/status/info.md
deleted file mode 100644
index 79fde1a55..000000000
--- a/data/library/api/status/info.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.info
-slug: /library/api-reference/status/st.info
-description: st.info displays an informational message.
----
-
-
diff --git a/data/library/api/status/progress.md b/data/library/api/status/progress.md
deleted file mode 100644
index f09325b29..000000000
--- a/data/library/api/status/progress.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.progress
-slug: /library/api-reference/status/st.progress
-description: st.progress displays a progress bar.
----
-
-
diff --git a/data/library/api/status/snow.md b/data/library/api/status/snow.md
deleted file mode 100644
index c8972afa2..000000000
--- a/data/library/api/status/snow.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.snow
-slug: /library/api-reference/status/st.snow
-description: st.snow displays celebratory snowflakes!
----
-
-
diff --git a/data/library/api/status/spinner.md b/data/library/api/status/spinner.md
deleted file mode 100644
index 7ccc0e9ee..000000000
--- a/data/library/api/status/spinner.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.spinner
-slug: /library/api-reference/status/st.spinner
-description: st.spinner temporarily displays a message while executing a block of code.
----
-
-
diff --git a/data/library/api/status/status.md b/data/library/api/status/status.md
deleted file mode 100644
index 0661a19a8..000000000
--- a/data/library/api/status/status.md
+++ /dev/null
@@ -1,202 +0,0 @@
----
-title: Display progress and status
-slug: /library/api-reference/status
----
-
-# Display progress and status
-
-Streamlit provides a few methods that allow you to add animation to your
-apps. These animations include progress bars, status messages (like
-warnings), and celebratory balloons.
-
-
-
-
-
-
-#### Progress bar
-
-Display a progress bar.
-
-```python
-for i in range(101):
- st.progress(i)
- do_something_slow()
-```
-
-
-
-
-
-
-#### Spinner
-
-Temporarily displays a message while executing a block of code.
-
-```python
-with st.spinner("Please wait..."):
- do_something_slow()
-```
-
-
-
-
-
-
-#### Toast
-
-Briefly displays a toast message in the bottom-right corner.
-
-```python
-st.toast('Butter!', icon='🧈')
-```
-
-
-
-
-
-
-#### Balloons
-
-Display celebratory balloons!
-
-```python
-st.balloons()
-```
-
-
-
-
-
-
-#### Snowflakes
-
-Display celebratory snowflakes!
-
-```python
-st.snow()
-```
-
-
-
-
-
-
-#### Error box
-
-Display error message.
-
-```python
-st.error("We encountered an error")
-```
-
-
-
-
-
-
-#### Warning box
-
-Display warning message.
-
-```python
-st.warning("Unable to fetch image. Skipping...")
-```
-
-
-
-
-
-
-#### Info box
-
-Display an informational message.
-
-```python
-st.info("Dataset is updated every day at midnight.")
-```
-
-
-
-
-
-
-#### Success box
-
-Display a success message.
-
-```python
-st.success("Match found!")
-```
-
-
-
-
-
-
-#### Exception output
-
-Display an exception.
-
-```python
-e = RuntimeError("This is an exception of type RuntimeError")
-st.exception(e)
-```
-
-
-
-
-
-
-
-
-
-
-#### Stqdm
-
-The simplest way to handle a progress bar in streamlit app. Created by [@Wirg](https://github.com/Wirg).
-
-```python
-from stqdm import stqdm
-
-for _ in stqdm(range(50)):
- sleep(0.5)
-```
-
-
-
-
-
-
-
-#### Custom notification box
-
-A custom notification box with the ability to close it out. Created by [@Socvest](https://github.com/Socvest).
-
-```python
-from streamlit_custom_notification_box import custom_notification_box
-
-styles = {'material-icons':{'color': 'red'}, 'text-icon-link-close-container': {'box-shadow': '#3896de 0px 4px'}, 'notification-text': {'':''}, 'close-button':{'':''}, 'link':{'':''}}
-custom_notification_box(icon='info', textDisplay='We are almost done with your registration...', externalLink='more info', url='#', styles=styles, key="foo")
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-from streamlit_extras.let_it_rain import rain
-
-rain(emoji="🎈", font_size=54,
- falling_speed=5, animation_length="infinite",)
-```
-
-
-
-
diff --git a/data/library/api/status/success.md b/data/library/api/status/success.md
deleted file mode 100644
index c6302c6f3..000000000
--- a/data/library/api/status/success.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.success
-slug: /library/api-reference/status/st.success
-description: st.success displays a success message.
----
-
-
diff --git a/data/library/api/status/toast.md b/data/library/api/status/toast.md
deleted file mode 100644
index 7b2b770bb..000000000
--- a/data/library/api/status/toast.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: st.toast
-slug: /library/api-reference/status/st.toast
-description: st.toast briefly displays a toast message in the bottom-right corner
----
-
-
-
-When multiple toasts are generated, they will stack. Hovering over a toast will
-stop it from disappearing. When hovering ends, the toast will disappear after
-four more seconds.
-
-```python
-import streamlit as st
-import time
-
-if st.button('Three cheers'):
- st.toast('Hip!')
- time.sleep(.5)
- st.toast('Hip!')
- time.sleep(.5)
- st.toast('Hooray!', icon='🎉')
-```
-
-
-
-Toast messages can also be updated. Assign `st.toast(my_message)` to a variable
-and use the `.toast()` method to update it. Note: if a toast has already disappeared
-or been dismissed, the update will not be seen.
-
-```python
-import streamlit as st
-import time
-
-def cook_breakfast():
- msg = st.toast('Gathering ingredients...')
- time.sleep(1)
- msg.toast('Cooking...')
- time.sleep(1)
- msg.toast('Ready!', icon = "🥞")
-
-if st.button('Cook breakfast'):
- cook_breakfast()
-```
-
-
diff --git a/data/library/api/status/warning.md b/data/library/api/status/warning.md
deleted file mode 100644
index ff0d212f2..000000000
--- a/data/library/api/status/warning.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.warning
-slug: /library/api-reference/status/st.warning
-description: st.warning displays warning message.
----
-
-
diff --git a/data/library/api/temp.txt b/data/library/api/temp.txt
deleted file mode 100644
index 8bd6648ed..000000000
--- a/data/library/api/temp.txt
+++ /dev/null
@@ -1 +0,0 @@
-asdf
diff --git a/data/library/api/text/caption.md b/data/library/api/text/caption.md
deleted file mode 100644
index 389a71372..000000000
--- a/data/library/api/text/caption.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: st.caption
-slug: /library/api-reference/text/st.caption
-description: st.caption displays text in small font.
----
-
-
-
-
diff --git a/data/library/api/text/code.md b/data/library/api/text/code.md
deleted file mode 100644
index 9795b4332..000000000
--- a/data/library/api/text/code.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: st.code
-slug: /library/api-reference/text/st.code
-description: st.code displays a code block with optional syntax highlighting.
----
-
-
-
-
diff --git a/data/library/api/text/divider.md b/data/library/api/text/divider.md
deleted file mode 100644
index ebb72e425..000000000
--- a/data/library/api/text/divider.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: st.divider
-slug: /library/api-reference/text/st.divider
-description: st.divider displays a horizontal rule in your app.
----
-
-
-
-Here's what it looks like in action when you have multiple elements in the app:
-
-```python
-import streamlit as st
-
-st.write("This is some text.")
-
-st.slider("This is a slider", 0, 100, (25, 75))
-
-st.divider() # 👈 Draws a horizontal rule
-
-st.write("This text is between the horizontal rules.")
-
-st.divider() # 👈 Another horizontal rule
-```
-
-
diff --git a/data/library/api/text/header.md b/data/library/api/text/header.md
deleted file mode 100644
index 42e04c2d3..000000000
--- a/data/library/api/text/header.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: st.header
-slug: /library/api-reference/text/st.header
-description: st.header displays text in header formatting.
----
-
-
-
-
diff --git a/data/library/api/text/latex.md b/data/library/api/text/latex.md
deleted file mode 100644
index b626551e6..000000000
--- a/data/library/api/text/latex.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: st.latex
-slug: /library/api-reference/text/st.latex
-description: st.latex displays mathematical expressions formatted as LaTeX.
----
-
-
-
-
diff --git a/data/library/api/text/markdown.md b/data/library/api/text/markdown.md
deleted file mode 100644
index 4b99a242b..000000000
--- a/data/library/api/text/markdown.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: st.markdown
-slug: /library/api-reference/text/st.markdown
-description: st.markdown displays string formatted as Markdown.
----
-
-
-
-
diff --git a/data/library/api/text/subheader.md b/data/library/api/text/subheader.md
deleted file mode 100644
index df36e7319..000000000
--- a/data/library/api/text/subheader.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: st.subheader
-slug: /library/api-reference/text/st.subheader
-description: st.subheader displays text in subheader formatting.
----
-
-
-
-
diff --git a/data/library/api/text/text-elements.md b/data/library/api/text/text-elements.md
deleted file mode 100644
index bc9a30acb..000000000
--- a/data/library/api/text/text-elements.md
+++ /dev/null
@@ -1,209 +0,0 @@
----
-title: Text elements
-slug: /library/api-reference/text
----
-
-# Text elements
-
-Streamlit apps usually start with a call to `st.title` to set the
-app's title. After that, there are 2 heading levels you can use:
-`st.header` and `st.subheader`.
-
-Pure text is entered with `st.text`, and Markdown with
-`st.markdown`.
-
-We also offer a "swiss-army knife" command called `st.write`, which accepts
-multiple arguments, and multiple data types. And as described above, you can
-also use [magic commands](/library/api-reference/write-magic/magic) in place of `st.write`.
-
-
-
-
-
-
-#### Markdown
-
-Display string formatted as Markdown.
-
-```python
-st.markdown("Hello **world**!")
-```
-
-
-
-
-
-
-#### Title
-
-Display text in title formatting.
-
-```python
-st.title("The app title")
-```
-
-
-
-
-
-
-#### Header
-
-Display text in header formatting.
-
-```python
-st.header("This is a header")
-```
-
-
-
-
-
-
-#### Subheader
-
-Display text in subheader formatting.
-
-```python
-st.subheader("This is a subheader")
-```
-
-
-
-
-
-
-#### Caption
-
-Display text in small font.
-
-```python
-st.caption("This is written small caption text")
-```
-
-
-
-
-
-
-#### Code block
-
-Display a code block with optional syntax highlighting.
-
-```python
-st.code("a = 1234")
-```
-
-
-
-
-
-
-#### Preformatted text
-
-Write fixed-width and preformatted text.
-
-```python
-st.text("Hello world")
-```
-
-
-
-
-
-
-#### LaTeX
-
-Display mathematical expressions formatted as LaTeX.
-
-```python
-st.latex("\int a x^2 \,dx")
-```
-
-
-
-
-
-
-#### Divider
-
-Display a horizontal rule.
-
-```python
-st.divider()
-```
-
-
-
-
-
-
-
-
-
-#### Annotated text
-
-Display annotated text in Streamlit apps. Created by [@tvst](https://github.com/tvst).
-
-```python
-annotated_text("This ", ("is", "verb"), " some ", ("annotated", "adj"), ("text", "noun"), " for those of ", ("you", "pronoun"), " who ", ("like", "verb"), " this sort of ", ("thing", "noun"), ".")
-```
-
-
-
-
-
-
-
-#### Drawable Canvas
-
-Provides a sketching canvas using [Fabric.js](http://fabricjs.com/). Created by [@andfanilo](https://github.com/andfanilo).
-
-```python
-st_canvas(fill_color="rgba(255, 165, 0, 0.3)", stroke_width=stroke_width, stroke_color=stroke_color, background_color=bg_color, background_image=Image.open(bg_image) if bg_image else None, update_streamlit=realtime_update, height=150, drawing_mode=drawing_mode, point_display_radius=point_display_radius if drawing_mode == 'point' else 0, key="canvas",)
-```
-
-
-
-
-
-
-
-#### Tags
-
-Add tags to your Streamlit apps. Created by [@gagan3012](https://github.com/gagan3012).
-
-```python
-st_tags(label='# Enter Keywords:', text='Press enter to add more', value=['Zero', 'One', 'Two'], suggestions=['five', 'six', 'seven', 'eight', 'nine', 'three', 'eleven', 'ten', 'four'], maxtags = 4, key='1')
-```
-
-
-
-
-
-
-
-#### NLU
-
-Apply text mining on a dataframe. Created by [@JohnSnowLabs](https://github.com/JohnSnowLabs/).
-
-```python
-nlu.load('sentiment').predict('I love NLU! <3')
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-mention(label="An awesome Streamlit App", icon="streamlit", url="https://extras.streamlit.app",)
-```
-
-
-
diff --git a/data/library/api/text/text.md b/data/library/api/text/text.md
deleted file mode 100644
index 14acc7b81..000000000
--- a/data/library/api/text/text.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: st.text
-slug: /library/api-reference/text/st.text
-description: st.text writes fixed-width and preformatted text.
----
-
-
-
-
diff --git a/data/library/api/text/title.md b/data/library/api/text/title.md
deleted file mode 100644
index e05aec904..000000000
--- a/data/library/api/text/title.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: st.title
-slug: /library/api-reference/text/st.title
-description: st.title displays text in title formatting.
----
-
-
-
-
diff --git a/data/library/api/utilities/echo.md b/data/library/api/utilities/echo.md
deleted file mode 100644
index 247b7b808..000000000
--- a/data/library/api/utilities/echo.md
+++ /dev/null
@@ -1,81 +0,0 @@
----
-title: st.echo
-slug: /library/api-reference/utilities/st.echo
-description: st.echo displays some code on the app, then execute it. Useful for tutorials.
----
-
-
-
-### Display code
-
-Sometimes you want your Streamlit app to contain _both_ your usual
-Streamlit graphic elements _and_ the code that generated those elements.
-That's where `st.echo()` comes in.
-
-Ok so let's say you have the following file, and you want to make its
-app a little bit more self-explanatory by making that middle section
-visible in the Streamlit app:
-
-```python
-import streamlit as st
-
-def get_user_name():
- return 'John'
-
-# ------------------------------------------------
-# Want people to see this part of the code...
-
-def get_punctuation():
- return '!!!'
-
-greeting = "Hi there, "
-user_name = get_user_name()
-punctuation = get_punctuation()
-
-st.write(greeting, user_name, punctuation)
-
-# ...up to here
-# ------------------------------------------------
-
-foo = 'bar'
-st.write('Done!')
-```
-
-The file above creates a Streamlit app containing the words "Hi there,
-`John`", and then "Done!".
-
-Now let's use `st.echo()` to make that middle section of the code visible
-in the app:
-
-```python
-import streamlit as st
-
-def get_user_name():
- return 'John'
-
-with st.echo():
- # Everything inside this block will be both printed to the screen
- # and executed.
-
- def get_punctuation():
- return '!!!'
-
- greeting = "Hi there, "
- value = get_user_name()
- punctuation = get_punctuation()
-
- st.write(greeting, value, punctuation)
-
-# And now we're back to _not_ printing to the screen
-foo = 'bar'
-st.write('Done!')
-```
-
-It's _that_ simple!
-
-
-
-You can have multiple `st.echo()` blocks in the same file.
-Use it as often as you wish!
-
-
diff --git a/data/library/api/utilities/experimental_get_query_params.md b/data/library/api/utilities/experimental_get_query_params.md
deleted file mode 100644
index 02e13b401..000000000
--- a/data/library/api/utilities/experimental_get_query_params.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: st.experimental_get_query_params
-slug: /library/api-reference/utilities/st.experimental_get_query_params
-description: st.experimental_get_query_params returns query parameters currently showing in the browser's URL bar.
----
-
-
-
-This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
-
-
-
-
diff --git a/data/library/api/utilities/experimental_set_query_params.md b/data/library/api/utilities/experimental_set_query_params.md
deleted file mode 100644
index 8c97e418b..000000000
--- a/data/library/api/utilities/experimental_set_query_params.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: st.experimental_set_query_params
-slug: /library/api-reference/utilities/st.experimental_set_query_params
-description: st.experimental_set_query_params sets query parameters shown in the browser's URL bar.
----
-
-
-
-This is an experimental feature. Experimental features and their APIs may change or be removed at any time. To learn more, click [here](/library/advanced-features/prerelease#experimental-features).
-
-
-
-
diff --git a/data/library/api/utilities/help.md b/data/library/api/utilities/help.md
deleted file mode 100644
index 67b435b7c..000000000
--- a/data/library/api/utilities/help.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.help
-slug: /library/api-reference/utilities/st.help
-description: st.help displays object's doc string, nicely formatted.
----
-
-
diff --git a/data/library/api/utilities/set_page_config.md b/data/library/api/utilities/set_page_config.md
deleted file mode 100644
index ae6678de3..000000000
--- a/data/library/api/utilities/set_page_config.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.set_page_config
-slug: /library/api-reference/utilities/st.set_page_config
-description: st.set_page_config configures the default settings of the page.
----
-
-
diff --git a/data/library/api/utilities/utilities.md b/data/library/api/utilities/utilities.md
deleted file mode 100644
index 2268dce22..000000000
--- a/data/library/api/utilities/utilities.md
+++ /dev/null
@@ -1,79 +0,0 @@
----
-title: Placeholders, help, and options
-slug: /library/api-reference/utilities
----
-
-# Placeholders, help, and options
-
-There are a handful of methods that allow you to create placeholders in your
-app, provide help using doc strings, get and modify configuration options and query parameters.
-
-
-
-
-#### Set page title, favicon, and more
-
-Configures the default settings of the page.
-
-```python
-st.set_page_config(
- page_title="My app",
- page_icon=":shark:",
-)
-```
-
-
-
-
-
-
-#### Echo
-
-Display some code on the app, then execute it. Useful for tutorials.
-
-```python
-with st.echo():
- st.write('This code will be printed')
-```
-
-
-
-
-#### Get help
-
-Display object’s doc string, nicely formatted.
-
-```python
-st.help(st.write)
-st.help(pd.DataFrame)
-```
-
-
-
-
-
-#### Get query parameters
-
-Return the query parameters that are currently showing in the browser's URL bar.
-
-```python
-st.experimental_get_query_params()
-```
-
-
-
-
-
-#### Set query parameters
-
-Set the query parameters that are shown in the browser's URL bar.
-
-```python
-st.experimental_set_query_params(
- show_map=True,
- selected=["asia"]
-)
-```
-
-
-
diff --git a/data/library/api/widgets/button.md b/data/library/api/widgets/button.md
deleted file mode 100644
index 7a121b066..000000000
--- a/data/library/api/widgets/button.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: st.button
-slug: /library/api-reference/widgets/st.button
-description: st.button displays a button widget.
-keywords: button
----
-
-
-
-### Advanced functionality
-
-Although a button is the simplest of input widgets, it's very common for buttons to be deeply tied to the use of [`st.session_state`](/library/api-reference/session-state). Check out our advanced guide on [Button behavior and examples](/library/advanced-features/button-behavior-and-examples).
-
-### Featured videos
-
-Check out our video on how to use one of Streamlit's core functions, the button!
-
-
-
-In the video below, we'll take it a step further and learn how to combine a [button](/library/api-reference/widgets/st.button), [checkbox](/library/api-reference/widgets/st.checkbox) and [radio button](/library/api-reference/widgets/st.radio)!
-
-
diff --git a/data/library/api/widgets/camera_input.md b/data/library/api/widgets/camera_input.md
deleted file mode 100644
index e4a226646..000000000
--- a/data/library/api/widgets/camera_input.md
+++ /dev/null
@@ -1,174 +0,0 @@
----
-title: st.camera_input
-slug: /library/api-reference/widgets/st.camera_input
-description: st.camera_input displays a widget to upload images from a camera
----
-
-
-
-To read the image file buffer as bytes, you can use `getvalue()` on the `UploadedFile` object.
-
-```python
-import streamlit as st
-
-img_file_buffer = st.camera_input("Take a picture")
-
-if img_file_buffer is not None:
- # To read image file buffer as bytes:
- bytes_data = img_file_buffer.getvalue()
- # Check the type of bytes_data:
- # Should output:
- st.write(type(bytes_data))
-```
-
-
-
-`st.camera_input` returns an object of the `UploadedFile` class, which a subclass of BytesIO. Therefore it is a "file-like" object. This means you can pass it anywhere where a file is expected, similar to `st.file_uploader`.
-
-
-
-## Image processing examples
-
-You can use the output of `st.camera_input` for various downstream tasks, including image processing. Below, we demonstrate how to use the `st.camera_input` widget with popular image and data processing libraries such as [Pillow](https://pillow.readthedocs.io/en/stable/installation.html), [NumPy](https://numpy.org/), [OpenCV](https://pypi.org/project/opencv-python-headless/), [TensorFlow](https://www.tensorflow.org/), [torchvision](https://pytorch.org/vision/stable/index.html), and [PyTorch](https://pytorch.org/).
-
-While we provide examples for the most popular use-cases and libraries, you are welcome to adapt these examples to your own needs and favorite libraries.
-
-### Pillow (PIL) and NumPy
-
-Ensure you have installed [Pillow](https://pillow.readthedocs.io/en/stable/installation.html) and [NumPy](https://numpy.org/).
-
-To read the image file buffer as a PIL Image and convert it to a NumPy array:
-
-```python
-import streamlit as st
-from PIL import Image
-import numpy as np
-
-img_file_buffer = st.camera_input("Take a picture")
-
-if img_file_buffer is not None:
- # To read image file buffer as a PIL Image:
- img = Image.open(img_file_buffer)
-
- # To convert PIL Image to numpy array:
- img_array = np.array(img)
-
- # Check the type of img_array:
- # Should output:
- st.write(type(img_array))
-
- # Check the shape of img_array:
- # Should output shape: (height, width, channels)
- st.write(img_array.shape)
-```
-
-### OpenCV (cv2)
-
-Ensure you have installed [OpenCV](https://pypi.org/project/opencv-python-headless/) and [NumPy](https://numpy.org/).
-
-To read the image file buffer with OpenCV:
-
-```python
-import streamlit as st
-import cv2
-import numpy as np
-
-img_file_buffer = st.camera_input("Take a picture")
-
-if img_file_buffer is not None:
- # To read image file buffer with OpenCV:
- bytes_data = img_file_buffer.getvalue()
- cv2_img = cv2.imdecode(np.frombuffer(bytes_data, np.uint8), cv2.IMREAD_COLOR)
-
- # Check the type of cv2_img:
- # Should output:
- st.write(type(cv2_img))
-
- # Check the shape of cv2_img:
- # Should output shape: (height, width, channels)
- st.write(cv2_img.shape)
-```
-
-### TensorFlow
-
-Ensure you have installed [TensorFlow](https://www.tensorflow.org/install/).
-
-To read the image file buffer as a 3 dimensional uint8 tensor with TensorFlow:
-
-```python
-import streamlit as st
-import tensorflow as tf
-
-img_file_buffer = st.camera_input("Take a picture")
-
-if img_file_buffer is not None:
- # To read image file buffer as a 3D uint8 tensor with TensorFlow:
- bytes_data = img_file_buffer.getvalue()
- img_tensor = tf.io.decode_image(bytes_data, channels=3)
-
- # Check the type of img_tensor:
- # Should output:
- st.write(type(img_tensor))
-
- # Check the shape of img_tensor:
- # Should output shape: (height, width, channels)
- st.write(img_tensor.shape)
-```
-
-### Torchvision
-
-Ensure you have installed [Torchvision](https://pypi.org/project/torchvision/) (it is not bundled with PyTorch) and [PyTorch](https://pytorch.org/).
-
-To read the image file buffer as a 3 dimensional uint8 tensor with `torchvision.io`:
-
-```python
-import streamlit as st
-import torch
-import torchvision
-
-img_file_buffer = st.camera_input("Take a picture")
-
-if img_file_buffer is not None:
- # To read image file buffer as a 3D uint8 tensor with `torchvision.io`:
- bytes_data = img_file_buffer.getvalue()
- torch_img = torchvision.io.decode_image(
- torch.frombuffer(bytes_data, dtype=torch.uint8)
- )
-
- # Check the type of torch_img:
- # Should output:
- st.write(type(torch_img))
-
- # Check the shape of torch_img:
- # Should output shape: torch.Size([channels, height, width])
- st.write(torch_img.shape)
-```
-
-### PyTorch
-
-Ensure you have installed [PyTorch](https://pytorch.org/) and [NumPy](https://numpy.org/).
-
-To read the image file buffer as a 3 dimensional uint8 tensor with PyTorch:
-
-```python
-import streamlit as st
-import torch
-import numpy as np
-
-img_file_buffer = st.camera_input("Take a picture")
-
-if img_file_buffer is not None:
- # To read image file buffer as a 3D uint8 tensor with PyTorch:
- bytes_data = img_file_buffer.getvalue()
- torch_img = torch.ops.image.decode_image(
- torch.from_numpy(np.frombuffer(bytes_data, np.uint8)), 3
- )
-
- # Check the type of torch_img:
- # Should output:
- st.write(type(torch_img))
-
- # Check the shape of torch_img:
- # Should output shape: torch.Size([channels, height, width])
- st.write(torch_img.shape)
-```
diff --git a/data/library/api/widgets/checkbox.md b/data/library/api/widgets/checkbox.md
deleted file mode 100644
index 9c19fa77a..000000000
--- a/data/library/api/widgets/checkbox.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: st.checkbox
-slug: /library/api-reference/widgets/st.checkbox
-description: st.checkbox displays a checkbox widget.
----
-
-
-
-### Featured videos
-
-Check out our video on how to use one of Streamlit's core functions, the checkbox! ☑
-
-
-
-In the video below, we'll take it a step further and learn how to combine a [button](/library/api-reference/widgets/st.button), [checkbox](/library/api-reference/widgets/st.checkbox) and [radio button](/library/api-reference/widgets/st.radio)!
-
-
diff --git a/data/library/api/widgets/color_picker.md b/data/library/api/widgets/color_picker.md
deleted file mode 100644
index 6f40d8be0..000000000
--- a/data/library/api/widgets/color_picker.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.color_picker
-slug: /library/api-reference/widgets/st.color_picker
-description: st.color_picker displays a color picker widget.
----
-
-
diff --git a/data/library/api/widgets/date_input.md b/data/library/api/widgets/date_input.md
deleted file mode 100644
index 921bd045d..000000000
--- a/data/library/api/widgets/date_input.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.date_input
-slug: /library/api-reference/widgets/st.date_input
-description: st.date_input displays a date input widget.
----
-
-
diff --git a/data/library/api/widgets/download_button.md b/data/library/api/widgets/download_button.md
deleted file mode 100644
index 7c038da6a..000000000
--- a/data/library/api/widgets/download_button.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.download_button
-slug: /library/api-reference/widgets/st.download_button
-description: st.download_button displays a download button widget.
----
-
-
diff --git a/data/library/api/widgets/file_uploader.md b/data/library/api/widgets/file_uploader.md
deleted file mode 100644
index 90b4567f6..000000000
--- a/data/library/api/widgets/file_uploader.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.file_uploader
-slug: /library/api-reference/widgets/st.file_uploader
-description: st.file_uploader displays a file uploader widget.
----
-
-
diff --git a/data/library/api/widgets/multiselect.md b/data/library/api/widgets/multiselect.md
deleted file mode 100644
index a5cc0b5e8..000000000
--- a/data/library/api/widgets/multiselect.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.multiselect
-slug: /library/api-reference/widgets/st.multiselect
-description: st.multiselect displays a multiselect widget. The multiselect widget starts as empty.
----
-
-
diff --git a/data/library/api/widgets/number_input.md b/data/library/api/widgets/number_input.md
deleted file mode 100644
index 8a5cfcbb0..000000000
--- a/data/library/api/widgets/number_input.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.number_input
-slug: /library/api-reference/widgets/st.number_input
-description: st.number_input displays a numeric input widget.
----
-
-
diff --git a/data/library/api/widgets/radio.md b/data/library/api/widgets/radio.md
deleted file mode 100644
index 822649903..000000000
--- a/data/library/api/widgets/radio.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: st.radio
-slug: /library/api-reference/widgets/st.radio
-description: st.radio displays a radio button widget.
----
-
-
-
-
-
-Widgets can customize how to hide their labels with the `label_visibility` parameter. If "hidden", the label doesn’t show but there is still empty space for it above the widget (equivalent to `label=""`). If "collapsed", both the label and the space are removed. Default is "visible". Radio buttons can also be disabled with the `disabled` parameter, and oriented horizontally with the `horizontal` parameter:
-
-```python
-import streamlit as st
-
-# Store the initial value of widgets in session state
-if "visibility" not in st.session_state:
- st.session_state.visibility = "visible"
- st.session_state.disabled = False
- st.session_state.horizontal = False
-
-col1, col2 = st.columns(2)
-
-with col1:
- st.checkbox("Disable radio widget", key="disabled")
- st.checkbox("Orient radio options horizontally", key="horizontal")
-
-with col2:
- st.radio(
- "Set label visibility 👇",
- ["visible", "hidden", "collapsed"],
- key="visibility",
- label_visibility=st.session_state.visibility,
- disabled=st.session_state.disabled,
- horizontal=st.session_state.horizontal,
- )
-```
-
-
-
-### Featured videos
-
-Check out our video on how to use one of Streamlit's core functions, the radio button! 🔘
-
-
-
-In the video below, we'll take it a step further and learn how to combine a [button](/library/api-reference/widgets/st.button), [checkbox](/library/api-reference/widgets/st.checkbox) and radio button!
-
-
diff --git a/data/library/api/widgets/select_slider.md b/data/library/api/widgets/select_slider.md
deleted file mode 100644
index e8a5450c7..000000000
--- a/data/library/api/widgets/select_slider.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-title: st.select_slider
-slug: /library/api-reference/widgets/st.select_slider
-description: st.select_slider displays a slider widget to select items from a list.
----
-
-
-
-### Featured videos
-
-Check out our video on how to use one of Streamlit's core functions, the select slider! 🎈
-
-
-In the video below, we'll take it a step further and make a double-ended slider.
-
diff --git a/data/library/api/widgets/selectbox.md b/data/library/api/widgets/selectbox.md
deleted file mode 100644
index edddeb928..000000000
--- a/data/library/api/widgets/selectbox.md
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: st.selectbox
-slug: /library/api-reference/widgets/st.selectbox
-description: st.selectbox displays a select widget.
----
-
-
-
-
-
-Select widgets can customize how to hide their labels with the `label_visibility` parameter. If "hidden", the label doesn’t show but there is still empty space for it above the widget (equivalent to `label=""`). If "collapsed", both the label and the space are removed. Default is "visible". Select widgets can also be disabled with the `disabled` parameter:
-
-```python
-import streamlit as st
-
-# Store the initial value of widgets in session state
-if "visibility" not in st.session_state:
- st.session_state.visibility = "visible"
- st.session_state.disabled = False
-
-col1, col2 = st.columns(2)
-
-with col1:
- st.checkbox("Disable selectbox widget", key="disabled")
- st.radio(
- "Set selectbox label visibility 👉",
- key="visibility",
- options=["visible", "hidden", "collapsed"],
- )
-
-with col2:
- option = st.selectbox(
- "How would you like to be contacted?",
- ("Email", "Home phone", "Mobile phone"),
- label_visibility=st.session_state.visibility,
- disabled=st.session_state.disabled,
- )
-```
-
-
diff --git a/data/library/api/widgets/slider.md b/data/library/api/widgets/slider.md
deleted file mode 100644
index fce3aa66b..000000000
--- a/data/library/api/widgets/slider.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-title: st.slider
-slug: /library/api-reference/widgets/st.slider
-description: st.slider displays a slider widget.
----
-
-
-
-### Featured videos
-
-Check out our video on how to use one of Streamlit's core functions, the slider!
-
-
-In the video below, we'll take it a step further and make a double-ended slider.
-
diff --git a/data/library/api/widgets/text_area.md b/data/library/api/widgets/text_area.md
deleted file mode 100644
index c3a7538e2..000000000
--- a/data/library/api/widgets/text_area.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.text_area
-slug: /library/api-reference/widgets/st.text_area
-description: st.text_area displays a multi-line text input widget.
----
-
-
diff --git a/data/library/api/widgets/text_input.md b/data/library/api/widgets/text_input.md
deleted file mode 100644
index 4c79e580f..000000000
--- a/data/library/api/widgets/text_input.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: st.text_input
-slug: /library/api-reference/widgets/st.text_input
-description: st.text_input displays a single-line text input widget.
----
-
-
-
-
-
-Text input widgets can customize how to hide their labels with the `label_visibility` parameter. If "hidden", the label doesn’t show but there is still empty space for it above the widget (equivalent to `label=""`). If "collapsed", both the label and the space are removed. Default is "visible". Text input widgets can also be disabled with the `disabled` parameter, and can display an optional placeholder text when the text input is empty using the `placeholder` parameter:
-
-```python
-import streamlit as st
-
-# Store the initial value of widgets in session state
-if "visibility" not in st.session_state:
- st.session_state.visibility = "visible"
- st.session_state.disabled = False
-
-col1, col2 = st.columns(2)
-
-with col1:
- st.checkbox("Disable text input widget", key="disabled")
- st.radio(
- "Set text input label visibility 👉",
- key="visibility",
- options=["visible", "hidden", "collapsed"],
- )
- st.text_input(
- "Placeholder for the other text input widget",
- "This is a placeholder",
- key="placeholder",
- )
-
-with col2:
- text_input = st.text_input(
- "Enter some text 👇",
- label_visibility=st.session_state.visibility,
- disabled=st.session_state.disabled,
- placeholder=st.session_state.placeholder,
- )
-
- if text_input:
- st.write("You entered: ", text_input)
-```
-
-
diff --git a/data/library/api/widgets/time_input.md b/data/library/api/widgets/time_input.md
deleted file mode 100644
index 3c753e84b..000000000
--- a/data/library/api/widgets/time_input.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: st.time_input
-slug: /library/api-reference/widgets/st.time_input
-description: st.time_input displays a time input widget.
----
-
-
diff --git a/data/library/api/widgets/widgets.md b/data/library/api/widgets/widgets.md
deleted file mode 100644
index a56e22577..000000000
--- a/data/library/api/widgets/widgets.md
+++ /dev/null
@@ -1,377 +0,0 @@
----
-title: Input widgets
-slug: /library/api-reference/widgets
----
-
-# Input widgets
-
-With widgets, Streamlit allows you to bake interactivity directly into your apps with buttons, sliders, text inputs, and more.
-
-
-
-
-
-
-#### Button
-
-Display a button widget.
-
-```python
-clicked = st.button("Click me")
-```
-
-
-
-
-
-
-
-#### Download button
-
-Display a download button widget.
-
-```python
-st.download_button("Download file", file)
-```
-
-
-
-
-
-
-#### Checkbox
-
-Display a checkbox widget.
-
-```python
-selected = st.checkbox("I agree")
-```
-
-
-
-
-
-
-#### Radio
-
-Display a radio button widget.
-
-```python
-choice = st.radio("Pick one", ["cats", "dogs"])
-```
-
-
-
-
-
-
-#### Selectbox
-
-Display a select widget.
-
-```python
-choice = st.selectbox("Pick one", ["cats", "dogs"])
-```
-
-
-
-
-
-
-#### Multiselect
-
-Display a multiselect widget. The multiselect widget starts as empty.
-
-```python
-choices = st.multiselect("Buy", ["milk", "apples", "potatoes"])
-```
-
-
-
-
-
-
-#### Slider
-
-Display a slider widget.
-
-```python
-number = st.slider("Pick a number", 0, 100)
-```
-
-
-
-
-
-
-#### Select slider
-
-Display a slider widget to select items from a list.
-
-```python
-size = st.select_slider("Pick a size", ["S", "M", "L"])
-```
-
-
-
-
-
-
-#### Text input
-
-Display a single-line text input widget.
-
-```python
-name = st.text_input("First name")
-```
-
-
-
-
-
-
-#### Number input
-
-Display a numeric input widget.
-
-```python
-choice = st.number_input("Pick a number", 0, 10)
-```
-
-
-
-
-
-
-#### Text area
-
-Display a multi-line text input widget.
-
-```python
-text = st.text_area("Text to translate")
-```
-
-
-
-
-
-
-#### Date input
-
-Display a date input widget.
-
-```python
-date = st.date_input("Your birthday")
-```
-
-
-
-
-
-
-#### Time input
-
-Display a time input widget.
-
-```python
-time = st.time_input("Meeting time")
-```
-
-
-
-
-
-
-#### File uploader
-
-Display a file uploader widget.
-
-```python
-data = st.file_uploader("Upload a CSV")
-```
-
-
-
-
-
-
-#### Camera input
-
-Display a widget that allows users to upload images directly from a camera.
-
-```python
-image = st.camera_input("Take a picture")
-```
-
-
-
-
-
-
-#### Color picker
-
-Display a color picker widget.
-
-```python
-color = st.color_picker("Pick a color")
-```
-
-
-
-
-
-
-
-
-
-
-#### Streamlit Elements
-
-Create a draggable and resizable dashboard in Streamlit. Created by [@okls](https://github.com/okls).
-
-```python
-from streamlit_elements import elements, mui, html
-
-with elements("new_element"):
- mui.Typography("Hello world")
-```
-
-
-
-
-
-
-
-#### Tags
-
-Add tags to your Streamlit apps. Created by [@gagan3012](https://github.com/gagan3012).
-
-```python
-from streamlit_tags import st_tags
-
-st_tags(label='# Enter Keywords:', text='Press enter to add more', value=['Zero', 'One', 'Two'],
-suggestions=['five', 'six', 'seven', 'eight', 'nine', 'three', 'eleven', 'ten', 'four'], maxtags = 4, key='1')
-```
-
-
-
-
-
-
-
-#### Stqdm
-
-The simplest way to handle a progress bar in streamlit app. Created by [@Wirg](https://github.com/Wirg).
-
-```python
-from stqdm import stqdm
-
-for _ in stqdm(range(50)):
- sleep(0.5)
-```
-
-
-
-
-
-
-
-#### Timeline
-
-Display a Timeline in Streamlit apps using [TimelineJS](https://timeline.knightlab.com/). Created by [@innerdoc](https://github.com/innerdoc).
-
-```python
-from streamlit_timeline import timeline
-
-with open('example.json', "r") as f:
- timeline(f.read(), height=800)
-```
-
-
-
-
-
-
-
-#### Camera input live
-
-Alternative for st.camera_input which returns the webcam images live. Created by [@blackary](https://github.com/blackary).
-
-```python
-from camera_input_live import camera_input_live
-
-image = camera_input_live()
-st.image(value)
-```
-
-
-
-
-
-
-
-#### Streamlit Ace
-
-Ace editor component for Streamlit. Created by [@okld](https://github.com/okld).
-
-```python
-from streamlit_ace import st_ace
-
-content = st_ace()
-content
-```
-
-
-
-
-
-
-
-#### Streamlit Chat
-
-Streamlit Component for a Chatbot UI. Created by [@AI-Yash](https://github.com/AI-Yash).
-
-```python
-from streamlit_chat import message
-
-message("My message")
-message("Hello bot!", is_user=True) # align's the message to the right
-```
-
-
-
-
-
-
-
-#### Streamlit Option Menu
-
-Select a single item from a list of options in a menu. Created by [@victoryhb](https://github.com/victoryhb).
-
-```python
-from streamlit_option_menu import option_menu
-
-option_menu("Main Menu", ["Home", 'Settings'],
- icons=['house', 'gear'], menu_icon="cast", default_index=1)
-```
-
-
-
-
-
-
-
-#### Streamlit Extras
-
-A library with useful Streamlit extras. Created by [@arnaudmiribel](https://github.com/arnaudmiribel/).
-
-```python
-from streamlit_extras.stoggle import stoggle
-
-stoggle(
- "Click me!", """🥷 Surprise! Here's some additional content""",)
-```
-
-
-
-
diff --git a/data/library/api/write-magic/magic.md b/data/library/api/write-magic/magic.md
deleted file mode 100644
index f6ce34ce1..000000000
--- a/data/library/api/write-magic/magic.md
+++ /dev/null
@@ -1,63 +0,0 @@
----
-title: Magic
-slug: /library/api-reference/write-magic/magic
----
-
-## Magic
-
-Magic commands are a feature in Streamlit that allows you to write almost anything (markdown, data,
-charts) without having to type an explicit command at all. Just put the thing you want to show on
-its own line of code, and it will appear in your app. Here's an example:
-
-```python
-# Draw a title and some text to the app:
-'''
-# This is the document title
-
-This is some _markdown_.
-'''
-
-import pandas as pd
-df = pd.DataFrame({'col1': [1,2,3]})
-df # 👈 Draw the dataframe
-
-x = 10
-'x', x # 👈 Draw the string 'x' and then the value of x
-
-# Also works with most supported chart types
-import matplotlib.pyplot as plt
-import numpy as np
-
-arr = np.random.normal(1, 1, size=100)
-fig, ax = plt.subplots()
-ax.hist(arr, bins=20)
-
-fig # 👈 Draw a Matplotlib chart
-```
-
-### How Magic works
-
-Any time Streamlit sees either a variable or literal
-value on its own line, it automatically writes that to your app using
-[`st.write`](/library/api-reference/write-magic/st.write) (which you'll learn about later).
-
-Also, magic is smart enough to ignore docstrings. That is, it ignores the
-strings at the top of files and functions.
-
-If you prefer to call Streamlit commands more explicitly, you can always turn
-magic off in your `~/.streamlit/config.toml` with the following setting:
-
-```toml
-[runner]
-magicEnabled = false
-```
-
-
-
Right now, Magic only works in the main Python app file, not in imported files. See GitHub issue #288 for a discussion of the issues.
-
-
-### Featured video
-
-Learn what the [`st.write`](/library/api-reference/write-magic/st.write) and [magic](/library/api-reference/write-magic/magic) commands are and how to use them.
-
-
diff --git a/data/library/api/write-magic/write-magic.md b/data/library/api/write-magic/write-magic.md
deleted file mode 100644
index 7e4366d04..000000000
--- a/data/library/api/write-magic/write-magic.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: st.write and magic commands
-slug: /library/api-reference/write-magic
----
-
-# st.write and magic commands
-
-Streamlit has two easy ways to display information into your app, which should typically be the
-first thing you try: `st.write` and magic.
-
-
-
-
-#### st.write
-
-Write arguments to the app.
-
-```python
-st.write("Hello **world**!")
-st.write(my_data_frame)
-st.write(my_mpl_figure)
-```
-
-
-
-
-#### Magic
-
-Any time Streamlit sees either a variable or literal value on its own line, it automatically writes that to your app using `st.write`
-
-```python
-"Hello **world**!"
-my_data_frame
-my_mpl_figure
-```
-
-
-
diff --git a/data/library/api/write-magic/write.md b/data/library/api/write-magic/write.md
deleted file mode 100644
index 2e4f9df88..000000000
--- a/data/library/api/write-magic/write.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: st.write
-slug: /library/api-reference/write-magic/st.write
-description: st.write writes arguments to the app.
----
-
-
-
-### Featured video
-
-Learn what the [`st.write`](/library/api-reference/write-magic/st.write) and [magic](/library/api-reference/write-magic/magic) commands are and how to use them.
-
-
diff --git a/data/library/components/components-api.md b/data/library/components/components-api.md
deleted file mode 100644
index 5d7b31c23..000000000
--- a/data/library/components/components-api.md
+++ /dev/null
@@ -1,321 +0,0 @@
----
-title: Components API
-slug: /library/components/components-api
----
-
-# Components API Reference
-
-The first step in developing a Streamlit Component is deciding whether to create a static component (i.e. rendered once, controlled by Python) or to create a bi-directional component that can communicate from Python to JavaScript and back.
-
-## Create a static component
-
-If your goal in creating a Streamlit Component is solely to display HTML code or render a chart from a Python visualization library, Streamlit provides two methods that greatly simplify the process: `components.html()` and `components.iframe()`.
-
-If you are unsure whether you need bi-directional communication, **start here first**!
-
-### Render an HTML string
-
-While [`st.text`](/library/api-reference/text/st.text), [`st.markdown`](/library/api-reference/text/st.markdown) and [`st.write`](/library/api-reference/write-magic/st.write) make it easy to write text to a Streamlit app, sometimes you'd rather implement a custom piece of HTML. Similarly, while Streamlit natively supports [many charting libraries](/library/api-reference/charts#chart-elements), you may want to implement a specific HTML/JavaScript template for a new charting library. `components.html` works by giving you the ability to embed an iframe inside of a Streamlit app that contains your desired output.
-
-
-
-**Example**
-
-```python
-import streamlit as st
-import streamlit.components.v1 as components
-
-# bootstrap 4 collapse example
-components.html(
- """
-
-
-
-
-
-
-
-
-
-
-
-
- Collapsible Group Item #1 content
-
-
-
-
-
-
-
-
-
-
-
- Collapsible Group Item #2 content
-
-
-
-
- """,
- height=600,
-)
-```
-
-### Render an iframe URL
-
-`components.iframe` is similar in features to `components.html`, with the difference being that `components.iframe` takes a URL as its input. This is used for situations where you want to include an entire page within a Streamlit app.
-
-
-
-**Example**
-
-```python
-import streamlit as st
-import streamlit.components.v1 as components
-
-# embed streamlit docs in a streamlit app
-components.iframe("https://docs.streamlit.io/en/latest")
-```
-
-## Create a bi-directional component
-
-A bi-directional Streamlit Component has two parts:
-
-1. A **frontend**, which is built out of HTML and any other web tech you like (JavaScript, React, Vue, etc.), and gets rendered in Streamlit apps via an iframe tag.
-2. A **Python API**, which Streamlit apps use to instantiate and talk to that frontend
-
-To make the process of creating bi-directional Streamlit Components easier, we've created a React template and a TypeScript-only template in the [Streamlit Component-template GitHub repo](https://github.com/streamlit/component-template). We also provide some [example Components](https://github.com/streamlit/component-template/tree/master/examples) in the same repo.
-
-### Development Environment Setup
-
-To build a Streamlit Component, you need the following installed in your development environment:
-
-- Python 3.8 - Python 3.11
-- Streamlit 1.11.1 or higher
-- [nodejs](https://nodejs.org/en/)
-- [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/)
-
-Clone the [component-template GitHub repo](https://github.com/streamlit/component-template), then decide whether you want to use the React.js (["template"](https://github.com/streamlit/component-template/tree/master/template)) or plain TypeScript (["template-reactless"](https://github.com/streamlit/component-template/tree/master/template-reactless)) template.
-
-1. Initialize and build the component template frontend from the terminal:
-
- ```bash
- # React template
- template/my_component/frontend
- npm install # Initialize the project and install npm dependencies
- npm run start # Start the Webpack dev server
-
- # or
-
- # TypeScript-only template
- template-reactless/my_component/frontend
- npm install # Initialize the project and install npm dependencies
- npm run start # Start the Webpack dev server
- ```
-
-2. _From a separate terminal_, run the Streamlit app (Python) that declares and uses the component:
-
- ```bash
- # React template
- cd template
- . venv/bin/activate # or similar to activate the venv/conda environment where Streamlit is installed
- streamlit run my_component/__init__.py # run the example
-
- # or
-
- # TypeScript-only template
- cd template-reactless
- . venv/bin/activate # or similar to activate the venv/conda environment where Streamlit is installed
- streamlit run my_component/__init__.py # run the example
- ```
-
-After running the steps above, you should see a Streamlit app in your browser that looks like this:
-
-
-
-The example app from the template shows how bi-directional communication is implemented. The Streamlit Component displays a button (`Python → JavaScript`), and the end-user can click the button. Each time the button is clicked, the JavaScript front-end increments the counter value and passes it back to Python (`JavaScript → Python`), which is then displayed by Streamlit (`Python → JavaScript`).
-
-### Frontend
-
-Because each Streamlit Component is its own webpage that gets rendered into an `iframe`, you can use just about any web tech you'd like to create that web page. We provide two templates to get started with in the Streamlit [Components-template GitHub repo](https://github.com/streamlit/component-template/); one of those templates uses [React](https://reactjs.org/) and the other does not.
-
-
-
-Even if you're not already familiar with React, you may still want to check out the React-based
-template. It handles most of the boilerplate required to send and receive data from Streamlit, and
-you can learn the bits of React you need as you go.
-
-If you'd rather not use React, please read this section anyway! It explains the fundamentals of
-Streamlit ↔ Component communication.
-
-
-#### React
-
-The React-based template is in `template/my_component/frontend/src/MyComponent.tsx`.
-
-- `MyComponent.render()` is called automatically when the component needs to be re-rendered (just like in any React app)
-- Arguments passed from the Python script are available via the `this.props.args` dictionary:
-
-```python
-# Send arguments in Python:
-result = my_component(greeting="Hello", name="Streamlit")
-```
-
-```javascript
-// Receive arguments in frontend:
-let greeting = this.props.args["greeting"]; // greeting = "Hello"
-let name = this.props.args["name"]; // name = "Streamlit"
-```
-
-- Use `Streamlit.setComponentValue()` to return data from the component to the Python script:
-
-```javascript
-// Set value in frontend:
-Streamlit.setComponentValue(3.14);
-```
-
-```python
-# Access value in Python:
-result = my_component(greeting="Hello", name="Streamlit")
-st.write("result = ", result) # result = 3.14
-```
-
-When you call `Streamlit.setComponentValue(new_value)`, that new value is sent to Streamlit, which then _re-executes the Python script from top to bottom_. When the script is re-executed, the call to `my_component(...)` will return the new value.
-
-From a _code flow_ perspective, it appears that you're transmitting data synchronously with the frontend: Python sends the arguments to JavaScript, and JavaScript returns a value to Python, all in a single function call! But in reality this is all happening _asynchronously_, and it's the re-execution of the Python script that achieves the sleight of hand.
-
-- Use `Streamlit.setFrameHeight()` to control the height of your component. By default, the React template calls this automatically (see `StreamlitComponentBase.componentDidUpdate()`). You can override this behavior if you need more control.
-- There's a tiny bit of magic in the last line of the file: `export default withStreamlitConnection(MyComponent)` - this does some handshaking with Streamlit, and sets up the mechanisms for bi-directional data communication.
-
-#### TypeScript-only
-
-The TypeScript-only template is in `template-reactless/my_component/frontend/src/MyComponent.tsx`.
-
-This template has much more code than its React sibling, in that all the mechanics of handshaking, setting up event listeners, and updating the component's frame height are done manually. The React version of the template handles most of these details automatically.
-
-- Towards the bottom of the source file, the template calls `Streamlit.setComponentReady()` to tell Streamlit it's ready to start receiving data. (You'll generally want to do this after creating and loading everything that the Component relies on.)
-- It subscribes to `Streamlit.RENDER_EVENT` to be notified of when to redraw. (This event won't be fired until `setComponentReady` is called)
-- Within its `onRender` event handler, it accesses the arguments passed in the Python script via `event.detail.args`
-- It sends data back to the Python script in the same way that the React template does—clicking on the "Click Me!" button calls `Streamlit.setComponentValue()`
-- It informs Streamlit when its height may have changed via `Streamlit.setFrameHeight()`
-
-#### Working with Themes
-
-
-
-Custom component theme support requires streamlit-component-lib version 1.2.0 or higher.
-
-
-
-Along with sending an `args` object to your component, Streamlit also sends
-a `theme` object defining the active theme so that your component can adjust
-its styling in a compatible way. This object is sent in the same message as
-`args`, so it can be accessed via `this.props.theme` (when using the React
-template) or `event.detail.theme` (when using the plain TypeScript template).
-
-The `theme` object has the following shape:
-
-```json
-{
- "base": "lightORdark",
- "primaryColor": "someColor1",
- "backgroundColor": "someColor2",
- "secondaryBackgroundColor": "someColor3",
- "textColor": "someColor4",
- "font": "someFont"
-}
-```
-
-The `base` option allows you to specify a preset Streamlit theme that your custom theme inherits from. Any theme config options not defined in your theme settings have their values set to those of the base theme. Valid values for `base` are `"light"` and `"dark"`.
-
-Note that the theme object has fields with the same names and semantics as the
-options in the "theme" section of the config options printed with the command
-`streamlit config show`.
-
-When using the React template, the following CSS variables are also set
-automatically.
-
-```css
---base
---primary-color
---background-color
---secondary-background-color
---text-color
---font
-```
-
-If you're not familiar with
-[CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties),
-the TLDR version is that you can use them like this:
-
-```css
-.mySelector {
- color: var(--text-color);
-}
-```
-
-These variables match the fields defined in the `theme` object above, and
-whether to use CSS variables or the theme object in your component is a matter
-of personal preference.
-
-#### Other frontend details
-
-- Because you're hosting your component from a dev server (via `npm run start`), any changes you make should be automatically reflected in the Streamlit app when you save.
-- If you want to add more packages to your component, run `npm add` to add them from within your component's `frontend/` directory.
-
-```bash
-npm add baseui
-```
-
-- To build a static version of your component, run `npm run build`. See [Prepare your Component](publish#prepare-your-component) for more information
-
-### Python API
-
-`components.declare_component()` is all that's required to create your Component's Python API:
-
-```python
- import streamlit.components.v1 as components
- my_component = components.declare_component(
- "my_component",
- url="http://localhost:3001"
- )
-```
-
-You can then use the returned `my_component` function to send and receive data with your frontend code:
-
-```python
-# Send data to the frontend using named arguments.
-return_value = my_component(name="Blackbeard", ship="Queen Anne's Revenge")
-
-# `my_component`'s return value is the data returned from the frontend.
-st.write("Value = ", return_value)
-```
-
-While the above is all you need to define from the Python side to have a working Component, we recommend creating a "wrapper" function with named arguments and default values, input validation and so on. This will make it easier for end-users to understand what data values your function accepts and allows for defining helpful docstrings.
-
-Please see [this example](https://github.com/streamlit/component-template/blob/master/template/my_component/__init__.py#L41-L77) from the Components-template for an example of creating a wrapper function.
-
-### Data serialization
-
-#### Python → Frontend
-
-You send data from Python to the frontend by passing keyword args to your Component's invoke function (that is, the function returned from `declare_component`). You can send the following types of data from Python to the frontend:
-
-- Any JSON-serializable data
-- `numpy.array`
-- `pandas.DataFrame`
-
-Any JSON-serializable data gets serialized to a JSON string, and deserialized to its JavaScript equivalent. `numpy.array` and `pandas.DataFrame` get serialized using [Apache Arrow](https://arrow.apache.org/) and are deserialized as instances of `ArrowTable`, which is a custom type that wraps Arrow structures and provides a convenient API on top of them.
-
-Check out the [CustomDataframe](https://github.com/streamlit/component-template/tree/master/examples/CustomDataframe) and [SelectableDataTable](https://github.com/streamlit/component-template/tree/master/examples/SelectableDataTable) Component example code for more context on how to use `ArrowTable`.
-
-#### Frontend → Python
-
-You send data from the frontend to Python via the `Streamlit.setComponentValue()` API (which is part of the template code). Unlike arg-passing from Python → frontend, **this API takes a single value**. If you want to return multiple values, you'll need to wrap them in an `Array` or `Object`.
-
-Custom Components can send JSON-serializable data from the frontend to Python, as well as [Apache Arrow](http://arrow.apache.org/) `ArrowTable`s to represent dataframes.
diff --git a/data/library/components/components.md b/data/library/components/components.md
deleted file mode 100644
index b17a577fb..000000000
--- a/data/library/components/components.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: Components
-slug: /library/components
----
-
-# Custom Components
-
-Components are third-party Python modules that extend what's possible with Streamlit.
-
-## How to use a Component
-
-Components are super easy to use:
-
-1. Start by finding the Component you'd like to use. Two great resources for this are:
-
- - The [Component gallery](https://streamlit.io/components)
- - [This thread](https://discuss.streamlit.io/t/streamlit-components-community-tracker/4634),
- by Fanilo A. from our forums.
-
-2. Install the Component using your favorite Python package manager. This step and all following
- steps are described in your component's instructions.
-
- For example, to use the fantastic [AgGrid
- Component](https://github.com/PablocFonseca/streamlit-aggrid), you first install it with:
-
- ```python
- pip install streamlit-aggrid
- ```
-
-3. In your Python code, import the Component as described in its instructions. For AgGrid, this step
- is:
-
- ```python
- from st_aggrid import AgGrid
- ```
-
-4. ...now you're ready to use it! For AgGrid, that's:
-
- ```python
- AgGrid(my_dataframe)
- ```
-
-## Making your own Component
-
-If you're interested in making your own component, check out the following resources:
-
-- [Create a Component](/library/components/create)
-- [Publish a Component](/library/components/publish)
-- [Components API](/library/components/components-api)
-- [Blog post for when we launched Components!](https://blog.streamlit.io/introducing-streamlit-components/)
-
-Alternatively, if you prefer to learn using videos, our engineer Tim Conkling has put together some
-amazing tutorials:
-
-##### Video tutorial, part 1
-
-
-
-##### Video tutorial, part 2
-
-
diff --git a/data/library/components/create-component.md b/data/library/components/create-component.md
deleted file mode 100644
index cbef01549..000000000
--- a/data/library/components/create-component.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: Create a Component
-slug: /library/components/create
----
-
-# Create a Component
-
-
-
-If you are only interested in **using Streamlit Components**, then you can skip this section and
-head over to the [Streamlit Components Gallery](https://streamlit.io/components) to find and install
-components created by the community!
-
-
-
-Developers can write JavaScript and HTML "components" that can be rendered in Streamlit apps. Streamlit Components can receive data from, and also send data to, Streamlit Python scripts.
-
-Streamlit Components let you expand the functionality provided in the base Streamlit package. Use Streamlit Components to create the needed functionality for your use-case, then wrap it up in a Python package and share with the broader Streamlit community!
-
-**Types of Streamlit Components you could create include:**
-
-- Custom versions of existing Streamlit elements and widgets, such as `st.slider` or `st.file_uploader`.
-- Completely new Streamlit elements and widgets by wrapping existing React.js, Vue.js, or other JavaScript widget toolkits.
-- Rendering Python objects having methods that output HTML, such as IPython [`__repr_html__`](https://ipython.readthedocs.io/en/stable/config/integrating.html#rich-display).
-- Convenience functions for commonly-used web features like [GitHub gists and Pastebin](https://github.com/randyzwitch/streamlit-embedcode).
-
-Check out these Streamlit Components tutorial videos by Streamlit engineer Tim Conkling to get started:
-
-## Part 1: Setup and Architecture
-
-
-
-## Part 2: Make a Slider Widget
-
-
diff --git a/data/library/components/publish-component.md b/data/library/components/publish-component.md
deleted file mode 100644
index ffee81825..000000000
--- a/data/library/components/publish-component.md
+++ /dev/null
@@ -1,104 +0,0 @@
----
-title: Publish a Component
-slug: /library/components/publish
----
-
-# Publish a Component
-
-## Publish to PyPI
-
-Publishing your Streamlit Component to [PyPI](https://pypi.org/) makes it easily accessible to Python users around the world. This step is completely optional, so if you won’t be releasing your component publicly, you can skip this section!
-
-
-
-For [static Streamlit Components](/library/components/components-api#create-a-static-component), publishing a Python package to PyPI follows the same steps as the
-[core PyPI packaging instructions](https://packaging.python.org/tutorials/packaging-projects/). A static Component likely contains only Python code, so once you have your
-[setup.py](https://packaging.python.org/tutorials/packaging-projects/#creating-setup-py) file correct and
-[generate your distribution files](https://packaging.python.org/tutorials/packaging-projects/#generating-distribution-archives), you're ready to
-[upload to PyPI](https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives).
-
-[Bi-directional Streamlit Components](/library/components/components-api#create-a-bi-directional-component) at minimum include both Python and JavaScript code, and as such, need a bit more preparation before they can be published on PyPI. The remainder of this page focuses on the bi-directional Component preparation process.
-
-
-
-### Prepare your Component
-
-A bi-directional Streamlit Component varies slightly from a pure Python library in that it must contain pre-compiled frontend code. This is how base Streamlit works as well; when you `pip install streamlit`, you are getting a Python library where the HTML and frontend code contained within it have been compiled into static assets.
-
-The [component-template](https://github.com/streamlit/component-template) GitHub repo provides the folder structure necessary for PyPI publishing. But before you can publish, you'll need to do a bit of housekeeping:
-
-1. Give your Component a name, if you haven't already
- - Rename the `template/my_component/` folder to `template//`
- - Pass your component's name as the the first argument to `declare_component()`
-2. Edit `MANIFEST.in`, change the path for recursive-include from `package/frontend/build *` to `/frontend/build *`
-3. Edit `setup.py`, adding your component's name and other relevant info
-4. Create a release build of your frontend code. This will add a new directory, `frontend/build/`, with your compiled frontend in it:
-
- ```bash
- cd frontend
- npm run build
- ```
-
-5. Pass the build folder's path as the `path` parameter to `declare_component`. (If you're using the template Python file, you can set `_RELEASE = True` at the top of the file):
-
- ```python
- import streamlit.components.v1 as components
-
- # Change this:
- # component = components.declare_component("my_component", url="http://localhost:3001")
-
- # To this:
- parent_dir = os.path.dirname(os.path.abspath(__file__))
- build_dir = os.path.join(parent_dir, "frontend/build")
- component = components.declare_component("new_component_name", path=build_dir)
- ```
-
-### Build a Python wheel
-
-Once you've changed the default `my_component` references, compiled the HTML and JavaScript code and set your new component name in `components.declare_component()`, you're ready to build a Python wheel:
-
-1. Make sure you have the latest versions of setuptools, wheel, and twine
-
-2. Create a wheel from the source code:
-
- ```bash
- # Run this from your component's top-level directory; that is,
- # the directory that contains `setup.py`
- python setup.py sdist bdist_wheel
- ```
-
-### Upload your wheel to PyPI
-
-With your wheel created, the final step is to upload to PyPI. The instructions here highlight how to upload to [Test PyPI](https://test.pypi.org/), so that you can learn the mechanics of the process without worrying about messing anything up. Uploading to PyPI follows the same basic procedure.
-
-1. Create an account on [Test PyPI](https://test.pypi.org/) if you don't already have one
-
- - Visit [https://test.pypi.org/account/register/](https://test.pypi.org/account/register/) and complete the steps
-
- - Visit [https://test.pypi.org/manage/account/#api-tokens](https://test.pypi.org/manage/account/#api-tokens) and create a new API token. Don’t limit the token scope to a particular project, since you are creating a new project. Copy your token before closing the page, as you won’t be able to retrieve it again.
-
-2. Upload your wheel to Test PyPI. `twine` will prompt you for a username and password. For the username, use **\_\_token\_\_**. For the password, use your token value from the previous step, including the `pypi-` prefix:
-
- ```bash
- python3 -m twine upload --repository testpypi dist/*
- ```
-
-3. Install your newly-uploaded package in a new Python project to make sure it works:
-
- ```bash
- python -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-pkg-YOUR-USERNAME-HERE
- ```
-
-If all goes well, you're ready to upload your library to PyPI by following the instructions at [https://packaging.python.org/tutorials/packaging-projects/#next-steps](https://packaging.python.org/tutorials/packaging-projects/#next-steps).
-
-Congratulations, you've created a publicly-available Streamlit Component!
-
-## Promote your Component!
-
-We'd love to help you share your Component with the Streamlit Community! To share it, please post on the [Streamlit 'Show the Community!' Forum category](https://discuss.streamlit.io/c/streamlit-examples/9) with the title similar to "New Component: ``, a new way to do X".
-
-You can also Tweet at us [@streamlit](https://twitter.com/streamlit) so that we can retweet your announcement for you.
-
-If you host your code on GitHub, add the tag `streamlit-component`, so that it's listed in the [GitHub **streamlit-component** topic](https://github.com/topics/streamlit-component):
-
-
diff --git a/data/library/get-started/create-an-app.md b/data/library/get-started/create-an-app.md
deleted file mode 100644
index e3354afc5..000000000
--- a/data/library/get-started/create-an-app.md
+++ /dev/null
@@ -1,409 +0,0 @@
----
-title: Create an app
-slug: /library/get-started/create-an-app
----
-
-# Create an app
-
-If you've made it this far, chances are you've
-[installed Streamlit](/library/get-started/installation) and
-run through the basics in our [Main concepts](/library/get-started/main-concepts) guide. If
-not, now is a good time to take a look.
-
-The easiest way to learn how to use Streamlit is to try things out yourself. As you read through this guide, test each method. As long as your app is running, every time you add a new element to your script and save, Streamlit's UI will ask if you'd like to rerun the app and view the changes. This allows you to work in a fast interactive loop: you write some code, save it, review the output, write some more, and so on, until you're happy with the results. The goal is to use Streamlit to create an interactive app for your data or model and along the way to use Streamlit to review, debug, perfect, and share your code.
-
-In this guide, you're going to use Streamlit's core features to
-create an interactive app; exploring a public Uber dataset for pickups and
-drop-offs in New York City. When you're finished, you'll know how to fetch
-and cache data, draw charts, plot information on a map, and use interactive
-widgets, like a slider, to filter results.
-
-
-
-If you'd like to skip ahead and see everything at once, the [complete script
-is available below](#lets-put-it-all-together).
-
-
-
-## Create your first app
-
-Streamlit is more than just a way to make data apps, it’s also a community of creators that share their apps and ideas and help each other make their work better. Please come join us on the community forum. We love to hear your questions, ideas, and help you work through your bugs — stop by today!
-
-1. The first step is to create a new Python script. Let's call it
- `uber_pickups.py`.
-
-2. Open `uber_pickups.py` in your favorite IDE or text editor, then add these
- lines:
-
- ```python
- import streamlit as st
- import pandas as pd
- import numpy as np
- ```
-
-3. Every good app has a title, so let's add one:
-
- ```python
- st.title('Uber pickups in NYC')
- ```
-
-4. Now it's time to run Streamlit from the command line:
-
- ```bash
- streamlit run uber_pickups.py
- ```
-
- Running a Streamlit app is no different than any other Python script. Whenever you need to view the app, you can use this command.
-
-
-
- Did you know you can also pass a URL to `streamlit run`? This is great when combined with GitHub Gists. For example:
-
- ```bash
- streamlit run https://raw.githubusercontent.com/streamlit/demo-uber-nyc-pickups/master/streamlit_app.py
- ```
-
-
-
-5. As usual, the app should automatically open in a new tab in your
- browser.
-
-## Fetch some data
-
-Now that you have an app, the next thing you'll need to do is fetch the Uber
-dataset for pickups and drop-offs in New York City.
-
-1. Let's start by writing a function to load the data. Add this code to your
- script:
-
- ```python
- DATE_COLUMN = 'date/time'
- DATA_URL = ('https://s3-us-west-2.amazonaws.com/'
- 'streamlit-demo-data/uber-raw-data-sep14.csv.gz')
-
- def load_data(nrows):
- data = pd.read_csv(DATA_URL, nrows=nrows)
- lowercase = lambda x: str(x).lower()
- data.rename(lowercase, axis='columns', inplace=True)
- data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
- return data
- ```
-
- You'll notice that `load_data` is a plain old function that downloads some
- data, puts it in a Pandas dataframe, and converts the date column from text
- to datetime. The function accepts a single parameter (`nrows`), which
- specifies the number of rows that you want to load into the dataframe.
-
-2. Now let's test the function and review the output. Below your function, add
- these lines:
-
- ```python
- # Create a text element and let the reader know the data is loading.
- data_load_state = st.text('Loading data...')
- # Load 10,000 rows of data into the dataframe.
- data = load_data(10000)
- # Notify the reader that the data was successfully loaded.
- data_load_state.text('Loading data...done!')
- ```
-
- You'll see a few buttons in the upper-right corner of your app asking if
- you'd like to rerun the app. Choose **Always rerun**, and you'll see your
- changes automatically each time you save.
-
-Ok, that's underwhelming...
-
-It turns out that it takes a long time to download data, and load 10,000 lines
-into a dataframe. Converting the date column into datetime isn’t a quick job
-either. You don’t want to reload the data each time the app is updated –
-luckily Streamlit allows you to cache the data.
-
-## Effortless caching
-
-1. Try adding `@st.cache_data` before the `load_data` declaration:
-
- ```python
- @st.cache_data
- def load_data(nrows):
- ```
-
-2. Then save the script, and Streamlit will automatically rerun your app. Since
- this is the first time you’re running the script with `@st.cache_data`, you won't
- see anything change. Let’s tweak your file a little bit more so that you can
- see the power of caching.
-
-3. Replace the line `data_load_state.text('Loading data...done!')` with this:
-
- ```python
- data_load_state.text("Done! (using st.cache_data)")
- ```
-
-4. Now save. See how the line you added appeared immediately? If you take a
- step back for a second, this is actually quite amazing. Something magical is
- happening behind the scenes, and it only takes one line of code to activate
- it.
-
-### How's it work?
-
-Let's take a few minutes to discuss how `@st.cache_data` actually works.
-
-When you mark a function with Streamlit’s cache annotation, it tells Streamlit
-that whenever the function is called that it should check two things:
-
-1. The input parameters you used for the function call.
-2. The code inside the function.
-
-If this is the first time Streamlit has seen both these items, with these exact
-values, and in this exact combination, it runs the function and stores the
-result in a local cache. The next time the function is called, if the two
-values haven't changed, then Streamlit knows it can skip executing the function
-altogether. Instead, it reads the output from the local cache and passes it on
-to the caller -- like magic.
-
-"But, wait a second," you’re saying to yourself, "this sounds too good to be
-true. What are the limitations of all this awesomesauce?"
-
-Well, there are a few:
-
-1. Streamlit will only check for changes within the current working directory.
- If you upgrade a Python library, Streamlit's cache will only notice this if
- that library is installed inside your working directory.
-2. If your function is not deterministic (that is, its output depends on random
- numbers), or if it pulls data from an external time-varying source (for
- example, a live stock market ticker service) the cached value will be
- none-the-wiser.
-3. Lastly, you should avoid mutating the output of a function cached with `st.cache_data` since cached
- values are stored by reference.
-
-While these limitations are important to keep in mind, they tend not to be an
-issue a surprising amount of the time. Those times, this cache is really
-transformational.
-
-
-
-Whenever you have a long-running computation in your code, consider
-refactoring it so you can use `@st.cache_data`, if possible. Please read [Caching](/library/advanced-features/caching) for more details.
-
-
-Now that you know how caching with Streamlit works, let’s get back to the Uber
-pickup data.
-
-## Inspect the raw data
-
-It's always a good idea to take a look at the raw data you're working with
-before you start working with it. Let's add a subheader and a printout of the
-raw data to the app:
-
-```python
-st.subheader('Raw data')
-st.write(data)
-```
-
-In the [Main concepts](/library/get-started/main-concepts) guide you learned that
-[`st.write`](/library/api-reference/write-magic/st.write) will render almost anything you pass
-to it. In this case, you're passing in a dataframe and it's rendering as an
-interactive table.
-
-[`st.write`](/library/api-reference/write-magic/st.write) tries to do the right thing based on
-the data type of the input. If it isn't doing what you expect you can use a
-specialized command like [`st.dataframe`](/library/api-reference/data/st.dataframe)
-instead. For a full list, see [API reference](/library/api-reference).
-
-## Draw a histogram
-
-Now that you've had a chance to take a look at the dataset and observe what's
-available, let's take things a step further and draw a histogram to see what
-Uber's busiest hours are in New York City.
-
-1. To start, let's add a subheader just below the raw data section:
-
- ```python
- st.subheader('Number of pickups by hour')
- ```
-
-2. Use NumPy to generate a histogram that breaks down pickup times binned by
- hour:
-
- ```python
- hist_values = np.histogram(
- data[DATE_COLUMN].dt.hour, bins=24, range=(0,24))[0]
- ```
-
-3. Now, let's use Streamlit's
- [`st.bar_chart()`](/library/api-reference/charts/st.bar_chart) method to draw this
- histogram.
-
- ```python
- st.bar_chart(hist_values)
- ```
-
-4. Save your script. This histogram should show up in your app right away.
- After a quick review, it looks like the busiest time is 17:00 (5 P.M.).
-
-To draw this diagram we used Streamlit's native `bar_chart()` method, but it's
-important to know that Streamlit supports more complex charting libraries like
-Altair, Bokeh, Plotly, Matplotlib and more. For a full list, see
-[supported charting libraries](/library/api-reference/charts).
-
-## Plot data on a map
-
-Using a histogram with Uber's dataset helped us determine what the busiest
-times are for pickups, but what if we wanted to figure out where pickups were
-concentrated throughout the city. While you could use a bar chart to show this
-data, it wouldn't be easy to interpret unless you were intimately familiar with
-latitudinal and longitudinal coordinates in the city. To show pickup
-concentration, let's use Streamlit [`st.map()`](/library/api-reference/charts/st.map)
-function to overlay the data on a map of New York City.
-
-1. Add a subheader for the section:
-
- ```python
- st.subheader('Map of all pickups')
- ```
-
-2. Use the `st.map()` function to plot the data:
-
- ```python
- st.map(data)
- ```
-
-3. Save your script. The map is fully interactive. Give it a try by panning or
- zooming in a bit.
-
-After drawing your histogram, you determined that the busiest hour for Uber
-pickups was 17:00. Let's redraw the map to show the concentration of pickups
-at 17:00.
-
-1. Locate the following code snippet:
-
- ```python
- st.subheader('Map of all pickups')
- st.map(data)
- ```
-
-2. Replace it with:
-
- ```python
- hour_to_filter = 17
- filtered_data = data[data[DATE_COLUMN].dt.hour == hour_to_filter]
- st.subheader(f'Map of all pickups at {hour_to_filter}:00')
- st.map(filtered_data)
- ```
-
-3. You should see the data update instantly.
-
-To draw this map we used the [`st.map`](/library/api-reference/charts/st.map) function that's built into Streamlit, but
-if you'd like to visualize complex map data, we encourage you to take a look at
-the [`st.pydeck_chart`](/library/api-reference/charts/st.pydeck_chart).
-
-## Filter results with a slider
-
-In the last section, when you drew the map, the time used to filter results was
-hardcoded into the script, but what if we wanted to let a reader dynamically
-filter the data in real time? Using Streamlit's widgets you can. Let's add a
-slider to the app with the `st.slider()` method.
-
-1. Locate `hour_to_filter` and replace it with this code snippet:
-
- ```python
- hour_to_filter = st.slider('hour', 0, 23, 17) # min: 0h, max: 23h, default: 17h
- ```
-
-2. Use the slider and watch the map update in real time.
-
-## Use a button to toggle data
-
-Sliders are just one way to dynamically change the composition of your app.
-Let's use the [`st.checkbox`](/library/api-reference/widgets/st.checkbox) function to add a
-checkbox to your app. We'll use this checkbox to show/hide the raw data
-table at the top of your app.
-
-1. Locate these lines:
-
- ```python
- st.subheader('Raw data')
- st.write(data)
- ```
-
-2. Replace these lines with the following code:
-
- ```python
- if st.checkbox('Show raw data'):
- st.subheader('Raw data')
- st.write(data)
- ```
-
-We're sure you've got your own ideas. When you're done with this tutorial, check out all the widgets that Streamlit exposes in our [API Reference](/library/api-reference).
-
-## Let's put it all together
-
-That's it, you've made it to the end. Here's the complete script for our interactive app.
-
-
-
-If you've skipped ahead, after you've created your script, the command to run
-Streamlit is `streamlit run [app name]`.
-
-
-
-```python
-import streamlit as st
-import pandas as pd
-import numpy as np
-
-st.title('Uber pickups in NYC')
-
-DATE_COLUMN = 'date/time'
-DATA_URL = ('https://s3-us-west-2.amazonaws.com/'
- 'streamlit-demo-data/uber-raw-data-sep14.csv.gz')
-
-@st.cache_data
-def load_data(nrows):
- data = pd.read_csv(DATA_URL, nrows=nrows)
- lowercase = lambda x: str(x).lower()
- data.rename(lowercase, axis='columns', inplace=True)
- data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
- return data
-
-data_load_state = st.text('Loading data...')
-data = load_data(10000)
-data_load_state.text("Done! (using st.cache_data)")
-
-if st.checkbox('Show raw data'):
- st.subheader('Raw data')
- st.write(data)
-
-st.subheader('Number of pickups by hour')
-hist_values = np.histogram(data[DATE_COLUMN].dt.hour, bins=24, range=(0,24))[0]
-st.bar_chart(hist_values)
-
-# Some number in the range 0-23
-hour_to_filter = st.slider('hour', 0, 23, 17)
-filtered_data = data[data[DATE_COLUMN].dt.hour == hour_to_filter]
-
-st.subheader('Map of all pickups at %s:00' % hour_to_filter)
-st.map(filtered_data)
-```
-
-## Share your app
-
-After you’ve built a Streamlit app, it's time to share it! To show it off to the world you can use **Streamlit Community Cloud** to deploy, manage, and share your app for free.
-
-It works in 3 simple steps:
-
-1. Put your app in a public GitHub repo (and make sure it has a requirements.txt!)
-2. Sign into [share.streamlit.io](https://share.streamlit.io)
-3. Click 'Deploy an app' and then paste in your GitHub URL
-
-That's it! 🎈 You now have a publicly deployed app that you can share with the world. Click to learn more about [how to use Streamlit Community Cloud](/streamlit-community-cloud).
-
-## Get help
-
-That's it for getting started, now you can go and build your own apps! If you
-run into difficulties here are a few things you can do.
-
-- Check out our [community forum](https://discuss.streamlit.io/) and post a question
-- Quick help from command line with `streamlit help`
-- Go through our [Knowledge Base](/knowledge-base) for tips, step-by-step tutorials, and articles that answer your questions about creating and deploying Streamlit apps.
-- Read more documentation! Check out:
- - [Advanced features](/library/advanced-features) for things like caching, theming, and adding statefulness to apps.
- - [API reference](/library/api-reference/) for examples of every Streamlit command.
diff --git a/data/library/get-started/index.md b/data/library/get-started/index.md
deleted file mode 100644
index 8e37c5259..000000000
--- a/data/library/get-started/index.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-title: Get started
-slug: /library/get-started
----
-
-# Get started
-
-This Get Started guide explains how Streamlit works, how to install Streamlit on your preferred
-operating system, and how to create your first Streamlit app!
-
-
-
- helps you set up your virtual environment and walks you through installing Streamlit on Windows, macOS, and Linux. Regardless of which package management tool and OS you're using, we recommend running the commands on this page in a virtual environment.
-
-
- introduces you to Streamlit's data model and development flow. You'll learn what makes Streamlit the most powerful way to build data apps, including the ability to display and style data, draw charts and maps, add interactive widgets, customize app layouts, cache computation, and define themes.
-
-
- using Streamlit's core features to fetch and cache data, draw charts, plot information on a map, and use interactive widgets, like a slider, to filter results.
-
-
- teaches you how to add pages to your app, including how to define pages, structure and run multipage apps, and navigate between pages. Once you understand the basics, create your first multipage app based on the familiar streamlit hello command!
-
- {/*
- to Streamlit Community Cloud. With Streamlit Community Cloud your data team can directly serve the needs of the rest of the company. Quickly go from data to app, from prototype to production. Share apps in one click and collaborate instantly with live code updates.
-*/}
-
-
-
diff --git a/data/library/get-started/installation.md b/data/library/get-started/installation.md
deleted file mode 100644
index 588616337..000000000
--- a/data/library/get-started/installation.md
+++ /dev/null
@@ -1,158 +0,0 @@
----
-title: Installation
-slug: /library/get-started/installation
----
-
-# Install Streamlit
-
-## Table of contents
-
-1. [Prerequisites](#prerequisites)
-2. [Install Streamlit on Windows](#install-streamlit-on-windows)
-3. [Install Streamlit on macOS/Linux](#install-streamlit-on-macoslinux)
-
-## Prerequisites
-
-Before you get started, you're going to need a few things:
-
-- Your favorite IDE or text editor
-- [Python 3.8 - Python 3.11](https://www.python.org/downloads/)
-- [PIP](https://pip.pypa.io/en/stable/installation/)
-
-## Set up your virtual environment
-
-Regardless of which package management tool you're using, we recommend running
-the commands on this page in a virtual environment. This ensures that the dependencies
-pulled in for Streamlit don't impact any other Python projects
-you're working on.
-
-Below are a few tools you can use for environment management:
-
-- [venv](https://docs.python.org/3/library/venv.html)
-- [pipenv](https://pipenv-fork.readthedocs.io/en/latest/)
-- [poetry](https://python-poetry.org/)
-- [virtualenv](https://virtualenv.pypa.io/en/latest/)
-- [conda](https://www.anaconda.com/distribution/)
-
-## Install Streamlit on Windows
-
-Streamlit's officially-supported environment manager on Windows is [Anaconda Navigator](https://docs.anaconda.com/free/navigator/).
-
-### Install Anaconda
-
-If you don't have Anaconda install yet, follow the steps provided on the [Anaconda installation page](https://docs.anaconda.com/free/anaconda/install/windows/).
-
-### Create a new environment with Streamlit
-
-Next you'll need to set up your environment.
-
-1. Follow the steps provided by Anaconda to [set up and manage your environment](https://docs.anaconda.com/free/navigator/getting-started/#navigator-managing-environments) using the Anaconda Navigator.
-
-2. Select the "▶" icon next to your new environment. Then select "Open terminal":
-
- 
-
-3. In the terminal that appears, type:
-
- ```bash
- pip install streamlit
- ```
-
-4. Test that the installation worked:
-
- ```bash
- streamlit hello
- ```
-
- Streamlit's Hello app should appear in a new tab in your web browser!
-
-### Use your new environment
-
-1. In Anaconda Navigator, open a terminal in your environment (see step 2 above).
-2. In the terminal that appears, use Streamlit as usual:
-
- ```bash
- streamlit run myfile.py
- ```
-
-## Install Streamlit on macOS/Linux
-
-Streamlit's officially-supported package manager and environment manager for macOS and Linux are [pip](https://pypi.org/project/pip/) and [venv](https://docs.python.org/3/library/venv.html), respectively. `venv` is a part of [The Python Standard Library](https://docs.python.org/3/library/index.html) and comes bundled with your installation of Python. See instructions on how to install and use `pip` below.
-
-### Install `pip`
-
-Install `pip`. More details about installing `pip` can be found in [pip's documentation](https://pip.pypa.io/en/stable/installation/#supported-methods).
-
-On a macOS:
-
-```bash
-python -m ensurepip --upgrade
-```
-
-On Ubuntu with Python 3:
-
-```bash
-sudo apt-get install python3-pip
-```
-
-For other Linux distributions, see [How to install PIP for Python](https://www.makeuseof.com/tag/install-pip-for-python/).
-
-### Install Xcode command line tools on macOS
-
-On macOS, you'll need to install Xcode command line tools. They are required to compile some of Streamlit's Python dependencies during installation. To install Xcode command line tools, run:
-
-```bash
-xcode-select --install
-```
-
-### Create a new environment with Streamlit
-
-1. Navigate to your project folder:
-
- ```bash
- cd myproject
- ```
-
-2. Create a new virtual environment in that folder and activate that environment:
-
- ```bash
- python -m venv .venv
- ```
-
- When you run the command above, a directory called `.venv` will appear in `myproject/`. This directory is where your virtual environment and its dependencies are installed.
-
-3. Install Streamlit in your environment:
-
- ```bash
- pip install streamlit
- ```
-
-4. Test that the installation worked:
-
- ```bash
- streamlit hello
- ```
-
- Streamlit's Hello app should appear in a new tab in your web browser!
-
-
-
-### Use your new environment
-
-1. Any time you want to use the new environment, you first need to go to your project folder (where the `.venv` directory lives) and run:
-
- ```bash
- source .venv/bin/activate
- ```
-
-2. Now you can use Python and Streamlit as usual:
-
- ```bash
- streamlit run myfile.py
- ```
-
- To stop the Streamlit server, press `ctrl-C`.
-
-3. When you're done using this environment, type `deactivate` to return to your normal shell.
-
-Now that you've installed Streamlit, take a few minutes to read through [Main concepts](/library/get-started/main-concepts) to understand Streamlit's data flow model.
diff --git a/data/library/get-started/main-concepts.md b/data/library/get-started/main-concepts.md
deleted file mode 100644
index bff5c2f40..000000000
--- a/data/library/get-started/main-concepts.md
+++ /dev/null
@@ -1,571 +0,0 @@
----
-title: Main concepts
-slug: /library/get-started/main-concepts
----
-
-# Main concepts
-
-Working with Streamlit is simple. First you sprinkle a few Streamlit commands
-into a normal Python script, then you run it with `streamlit run`:
-
-```bash
-streamlit run your_script.py [-- script args]
-```
-
-As soon as you run the script as shown above, a local Streamlit server will
-spin up and your app will open in a new tab in your default web browser. The app
-is your canvas, where you'll draw charts, text, widgets, tables, and more.
-
-What gets drawn in the app is up to you. For example
-[`st.text`](/library/api-reference/text/st.text) writes raw text to your app, and
-[`st.line_chart`](/library/api-reference/charts/st.line_chart) draws — you guessed it — a
-line chart. Refer to our [API documentation](/library/api-reference) to see all commands that
-are available to you.
-
-
-
-When passing your script some custom arguments, they must be passed after two dashes. Otherwise the
-arguments get interpreted as arguments to Streamlit itself.
-
-
-
-Another way of running Streamlit is to run it as a Python module. This can be
-useful when configuring an IDE like PyCharm to work with Streamlit:
-
-```bash
-# Running
-python -m streamlit run your_script.py
-
-# is equivalent to:
-streamlit run your_script.py
-```
-
-
-
-You can also pass a URL to `streamlit run`! This is great when combined with
-GitHub Gists. For example:
-
-```bash
-streamlit run https://raw.githubusercontent.com/streamlit/demo-uber-nyc-pickups/master/streamlit_app.py
-```
-
-
-
-## Development flow
-
-Every time you want to update your app, save the source file. When you do
-that, Streamlit detects if there is a change and asks you whether you want to
-rerun your app. Choose "Always rerun" at the top-right of your screen to
-automatically update your app every time you change its source code.
-
-This allows you to work in a fast interactive loop: you type some code, save
-it, try it out live, then type some more code, save it, try it out, and so on
-until you're happy with the results. This tight loop between coding and viewing
-results live is one of the ways Streamlit makes your life easier.
-
-
-
-While developing a Streamlit app, it's recommended to lay out your editor and
-browser windows side by side, so the code and the app can be seen at the same
-time. Give it a try!
-
-
-
-As of Streamlit version 1.10.0 and higher, Streamlit apps cannot be run from the root directory of Linux distributions. If you try to run a Streamlit app from the root directory, Streamlit will throw a `FileNotFoundError: [Errno 2] No such file or directory` error. For more information, see GitHub issue [#5239](https://github.com/streamlit/streamlit/issues/5239).
-
-If you are using Streamlit version 1.10.0 or higher, your main script should live in a directory other than the root directory. When using Docker, you can use the `WORKDIR` command to specify the directory where your main script lives. For an example of how to do this, read [Create a Dockerfile](/knowledge-base/tutorials/deploy/docker#create-a-dockerfile).
-
-## Data flow
-
-Streamlit's architecture allows you to write apps the same way you write plain
-Python scripts. To unlock this, Streamlit apps have a unique data flow: any
-time something must be updated on the screen, Streamlit reruns your entire
-Python script from top to bottom.
-
-This can happen in two situations:
-
-- Whenever you modify your app's source code.
-
-- Whenever a user interacts with widgets in the app. For example, when dragging
- a slider, entering text in an input box, or clicking a button.
-
-Whenever a callback is passed to a widget via the `on_change` (or `on_click`) parameter, the callback will always run before the rest of your script. For details on the Callbacks API, please refer to our [Session State API Reference Guide](/library/api-reference/session-state#use-callbacks-to-update-session-state).
-
-And to make all of this fast and seamless, Streamlit does some heavy lifting
-for you behind the scenes. A big player in this story is the
-[`@st.cache_data`](#caching) decorator, which allows developers to skip certain
-costly computations when their apps rerun. We'll cover caching later in this
-page.
-
-## Display and style data
-
-There are a few ways to display data (tables, arrays, data frames) in Streamlit
-apps. [Below](/library/get-started/main-concepts#use-magic), you will be introduced to _magic_
-and [`st.write()`](/library/api-reference/write-magic/st.write), which can be used to write
-anything from text to tables. After that, let's take a look at methods designed
-specifically for visualizing data.
-
-### Use magic
-
-You can also write to your app without calling any Streamlit methods.
-Streamlit supports "[magic commands](/library/api-reference/write-magic/magic)," which means you don't have to use
-[`st.write()`](/library/api-reference/write-magic/st.write) at all! To see this in action try this snippet:
-
-```python
-"""
-# My first app
-Here's our first attempt at using data to create a table:
-"""
-
-import streamlit as st
-import pandas as pd
-df = pd.DataFrame({
- 'first column': [1, 2, 3, 4],
- 'second column': [10, 20, 30, 40]
-})
-
-df
-```
-
-Any time that Streamlit sees a variable or a literal
-value on its own line, it automatically writes that to your app using
-[`st.write()`](/library/api-reference/write-magic/st.write). For more information, refer to the
-documentation on [magic commands](/library/api-reference/write-magic/magic).
-
-### Write a data frame
-
-Along with [magic commands](/library/api-reference/write-magic/magic),
-[`st.write()`](/library/api-reference/write-magic/st.write) is Streamlit's "Swiss Army knife". You
-can pass almost anything to [`st.write()`](/library/api-reference/write-magic/st.write):
-text, data, Matplotlib figures, Altair charts, and more. Don't worry, Streamlit
-will figure it out and render things the right way.
-
-```python
-import streamlit as st
-import pandas as pd
-
-st.write("Here's our first attempt at using data to create a table:")
-st.write(pd.DataFrame({
- 'first column': [1, 2, 3, 4],
- 'second column': [10, 20, 30, 40]
-}))
-```
-
-There are other data specific functions like
-[`st.dataframe()`](/library/api-reference/data/st.dataframe) and
-[`st.table()`](/library/api-reference/data/st.table) that you can also use for displaying
-data. Let's understand when to use these features and how to add colors and styling to your data frames.
-
-You might be asking yourself, "why wouldn't I always use `st.write()`?" There are
-a few reasons:
-
-1. _Magic_ and [`st.write()`](/library/api-reference/write-magic/st.write) inspect the type of
- data that you've passed in, and then decide how to best render it in the
- app. Sometimes you want to draw it another way. For example, instead of
- drawing a dataframe as an interactive table, you may want to draw it as a
- static table by using `st.table(df)`.
-2. The second reason is that other methods return an object that can be used
- and modified, either by adding data to it or replacing it.
-3. Finally, if you use a more specific Streamlit method you can pass additional
- arguments to customize its behavior.
-
-For example, let's create a data frame and change its formatting with a Pandas
-`Styler` object. In this example, you'll use Numpy to generate a random sample,
-and the [`st.dataframe()`](/library/api-reference/data/st.dataframe) method to draw an
-interactive table.
-
-
-
-This example uses Numpy to generate a random sample, but you can use Pandas
-DataFrames, Numpy arrays, or plain Python arrays.
-
-
-
-```python
-import streamlit as st
-import numpy as np
-
-dataframe = np.random.randn(10, 20)
-st.dataframe(dataframe)
-```
-
-Let's expand on the first example using the Pandas `Styler` object to highlight
-some elements in the interactive table.
-
-```python
-import streamlit as st
-import numpy as np
-import pandas as pd
-
-dataframe = pd.DataFrame(
- np.random.randn(10, 20),
- columns=('col %d' % i for i in range(20)))
-
-st.dataframe(dataframe.style.highlight_max(axis=0))
-```
-
-Streamlit also has a method for static table generation:
-[`st.table()`](/library/api-reference/data/st.table).
-
-```python
-import streamlit as st
-import numpy as np
-import pandas as pd
-
-dataframe = pd.DataFrame(
- np.random.randn(10, 20),
- columns=('col %d' % i for i in range(20)))
-st.table(dataframe)
-```
-
-### Draw charts and maps
-
-Streamlit supports several popular data charting libraries like [Matplotlib,
-Altair, deck.gl, and more](/library/api-reference#chart-elements). In this section, you'll
-add a bar chart, line chart, and a map to your app.
-
-### Draw a line chart
-
-You can easily add a line chart to your app with
-[`st.line_chart()`](/library/api-reference/charts/st.line_chart). We'll generate a random
-sample using Numpy and then chart it.
-
-```python
-import streamlit as st
-import numpy as np
-import pandas as pd
-
-chart_data = pd.DataFrame(
- np.random.randn(20, 3),
- columns=['a', 'b', 'c'])
-
-st.line_chart(chart_data)
-```
-
-### Plot a map
-
-With [`st.map()`](/library/api-reference/charts/st.map) you can display data points on a map.
-Let's use Numpy to generate some sample data and plot it on a map of
-San Francisco.
-
-```python
-import streamlit as st
-import numpy as np
-import pandas as pd
-
-map_data = pd.DataFrame(
- np.random.randn(1000, 2) / [50, 50] + [37.76, -122.4],
- columns=['lat', 'lon'])
-
-st.map(map_data)
-```
-
-## Widgets
-
-When you've got the data or model into the state that you want to explore, you
-can add in widgets like [`st.slider()`](/library/api-reference/widgets/st.slider),
-[`st.button()`](/library/api-reference/widgets/st.button) or
-[`st.selectbox()`](/library/api-reference/widgets/st.selectbox). It's really straightforward
-— treat widgets as variables:
-
-```python
-import streamlit as st
-x = st.slider('x') # 👈 this is a widget
-st.write(x, 'squared is', x * x)
-```
-
-On first run, the app above should output the text "0 squared is 0". Then
-every time a user interacts with a widget, Streamlit simply reruns your script
-from top to bottom, assigning the current state of the widget to your variable
-in the process.
-
-For example, if the user moves the slider to position `10`, Streamlit will
-rerun the code above and set `x` to `10` accordingly. So now you should see the
-text "10 squared is 100".
-
-Widgets can also be accessed by key, if you choose to specify a string to use as the unique key for the widget:
-
-```python
-import streamlit as st
-st.text_input("Your name", key="name")
-
-# You can access the value at any point with:
-st.session_state.name
-```
-
-Every widget with a key is automatically added to Session State. For more information about Session State, its association with widget state, and its limitations, see [Session State API Reference Guide](/library/api-reference/session-state).
-
-### Use checkboxes to show/hide data
-
-One use case for checkboxes is to hide or show a specific chart or section in
-an app. [`st.checkbox()`](/library/api-reference/widgets/st.checkbox) takes a single argument,
-which is the widget label. In this sample, the checkbox is used to toggle a
-conditional statement.
-
-```python
-import streamlit as st
-import numpy as np
-import pandas as pd
-
-if st.checkbox('Show dataframe'):
- chart_data = pd.DataFrame(
- np.random.randn(20, 3),
- columns=['a', 'b', 'c'])
-
- chart_data
-```
-
-### Use a selectbox for options
-
-Use [`st.selectbox`](/library/api-reference/widgets/st.selectbox) to choose from a series. You
-can write in the options you want, or pass through an array or data frame
-column.
-
-Let's use the `df` data frame we created earlier.
-
-```python
-import streamlit as st
-import pandas as pd
-
-df = pd.DataFrame({
- 'first column': [1, 2, 3, 4],
- 'second column': [10, 20, 30, 40]
- })
-
-option = st.selectbox(
- 'Which number do you like best?',
- df['first column'])
-
-'You selected: ', option
-```
-
-## Layout
-
-Streamlit makes it easy to organize your widgets in a left panel sidebar with
-[`st.sidebar`](/library/api-reference/layout/st.sidebar). Each element that's passed to
-[`st.sidebar`](/library/api-reference/layout/st.sidebar) is pinned to the left, allowing
-users to focus on the content in your app while still having access to UI
-controls.
-
-For example, if you want to add a selectbox and a slider to a sidebar,
-use `st.sidebar.slider` and `st.sidebar.selectbox` instead of `st.slider` and
-`st.selectbox`:
-
-```python
-import streamlit as st
-
-# Add a selectbox to the sidebar:
-add_selectbox = st.sidebar.selectbox(
- 'How would you like to be contacted?',
- ('Email', 'Home phone', 'Mobile phone')
-)
-
-# Add a slider to the sidebar:
-add_slider = st.sidebar.slider(
- 'Select a range of values',
- 0.0, 100.0, (25.0, 75.0)
-)
-```
-
-Beyond the sidebar, Streamlit offers several other ways to control the layout
-of your app. [`st.columns`](/library/api-reference/layout/st.columns) lets you place widgets side-by-side, and
-[`st.expander`](/library/api-reference/layout/st.expander) lets you conserve space by hiding away large content.
-
-```python
-import streamlit as st
-
-left_column, right_column = st.columns(2)
-# You can use a column just like st.sidebar:
-left_column.button('Press me!')
-
-# Or even better, call Streamlit functions inside a "with" block:
-with right_column:
- chosen = st.radio(
- 'Sorting hat',
- ("Gryffindor", "Ravenclaw", "Hufflepuff", "Slytherin"))
- st.write(f"You are in {chosen} house!")
-```
-
-
-
-`st.echo` and `st.spinner` are not currently supported inside the sidebar
-or layout options. Rest assured, though, we're currently working on adding support for those too!
-
-
-
-### Show progress
-
-When adding long running computations to an app, you can use
-[`st.progress()`](/library/api-reference/status/st.progress) to display status in real time.
-
-First, let's import time. We're going to use the `time.sleep()` method to
-simulate a long running computation:
-
-```python
-import time
-```
-
-Now, let's create a progress bar:
-
-```python
-import streamlit as st
-import time
-
-'Starting a long computation...'
-
-# Add a placeholder
-latest_iteration = st.empty()
-bar = st.progress(0)
-
-for i in range(100):
- # Update the progress bar with each iteration.
- latest_iteration.text(f'Iteration {i+1}')
- bar.progress(i + 1)
- time.sleep(0.1)
-
-'...and now we\'re done!'
-```
-
-## Themes
-
-Streamlit supports Light and Dark themes out of the box. Streamlit will first
-check if the user viewing an app has a Light or Dark mode preference set by
-their operating system and browser. If so, then that preference will be used.
-Otherwise, the Light theme is applied by default.
-
-You can also change the active theme from "⋮" → "Settings".
-
-
-
-Want to add your own theme to an app? The "Settings" menu has a theme editor
-accessible by clicking on "Edit active theme". You can use this editor to try
-out different colors and see your app update live.
-
-
-
-When you're happy with your work, themes can be saved by
-[setting config options](/library/advanced-features/configuration#set-configuration-options)
-in the `[theme]` config section. After you've defined a theme for your app, it
-will appear as "Custom Theme" in the theme selector and will be applied by
-default instead of the included Light and Dark themes.
-
-More information about the options available when defining a theme can be found
-in the [theme option documentation](/library/advanced-features/theming).
-
-
-
-The theme editor menu is available only in local development. If you've deployed your app using
-Streamlit Community Cloud, the "Edit active theme" button will no longer be displayed in the "Settings"
-menu.
-
-
-
-
-
-Another way to experiment with different theme colors is to turn on the "Run on save" option, edit
-your config.toml file, and watch as your app reruns with the new theme colors applied.
-
-
-
-## Caching
-
-The Streamlit cache allows your app to stay performant even when loading data from the web, manipulating large datasets, or performing expensive computations.
-
-The basic idea behind caching is to store the results of expensive function calls and return the cached result when the same inputs occur again rather than calling the function on subsequent runs.
-
-To cache a function in Streamlit, you need to decorate it with one of two decorators (`st.cache_data` and `st.cache_resource`):
-
-```python
-@st.cache_data
-def long_running_function(param1, param2):
- return …
-```
-
-In this example, decorating `long_running_function` with `@st.cache_data` tells Streamlit that whenever the function is called, it checks two things:
-
-1. The values of the input parameters (in this case, `param1` and `param2`).
-2. The code inside the function.
-
-If this is the first time Streamlit sees these parameter values and function code, it runs the function and stores the return value in a cache. The next time the function is called with the same parameters and code (e.g., when a user interacts with the app), Streamlit will skip executing the function altogether and return the cached value instead. During development, the cache updates automatically as the function code changes, ensuring that the latest changes are reflected in the cache.
-
-As mentioned, there are two caching decorators:
-
-- `st.cache_data` is the recommended way to cache computations that return data: loading a DataFrame from CSV, transforming a NumPy array, querying an API, or any other function that returns a serializable data object (str, int, float, DataFrame, array, list, …). It creates a new copy of the data at each function call, making it safe against [mutations and race conditions](/library/advanced-features/caching#mutation-and-concurrency-issues). The behavior of `st.cache_data` is what you want in most cases – so if you're unsure, start with `st.cache_data` and see if it works!
-- `st.cache_resource` is the recommended way to cache global resources like ML models or database connections – unserializable objects that you don’t want to load multiple times. Using it, you can share these resources across all reruns and sessions of an app without copying or duplication. Note that any mutations to the cached return value directly mutate the object in the cache (more details below).
-
-
-
-For more information about the Streamlit caching decorators, their configuration parameters, and their limitations, see [Caching](/library/advanced-features/caching).
-
-## Pages
-
-As apps grow large, it becomes useful to organize them into multiple pages. This makes the app easier to manage as a developer and easier to navigate as a user. Streamlit provides a frictionless way to create multipage apps.
-
-We designed this feature so that building a multipage app is as easy as building a single-page app! Just add more pages to an existing app as follows:
-
-1. In the folder containing your main script, create a new `pages` folder. Let’s say your main script is named `main_page.py`.
-2. Add new `.py` files in the `pages` folder to add more pages to your app.
-3. Run `streamlit run main_page.py` as usual.
-
-That’s it! The `main_page.py` script will now correspond to the main page of your app. And you’ll see the other scripts from the `pages` folder in the sidebar page selector. For example:
-
-
-main_page.py
-
-```python
-import streamlit as st
-
-st.markdown("# Main page 🎈")
-st.sidebar.markdown("# Main page 🎈")
-```
-
-
-
-
-pages/page_2.py
-
-```python
-import streamlit as st
-
-st.markdown("# Page 2 ❄️")
-st.sidebar.markdown("# Page 2 ❄️")
-```
-
-
-
-
-pages/page_3.py
-
-```python
-import streamlit as st
-
-st.markdown("# Page 3 🎉")
-st.sidebar.markdown("# Page 3 🎉")
-```
-
-
-
-
-Now run `streamlit run main_page.py` and view your shiny new multipage app!
-
-
-
-Our documentation on [Multipage apps](/library/get-started/multipage-apps) teaches you how to add pages to your app, including how to define pages, structure and run multipage apps, and navigate between pages. Once you understand the basics, [create your first multipage app](/library/get-started/multipage-apps/create-a-multipage-app)!
-
-## App model
-
-Now that you know a little more about all the individual pieces, let's close
-the loop and review how it works together:
-
-1. Streamlit apps are Python scripts that run from top to bottom
-1. Every time a user opens a browser tab pointing to your app, the script is
- re-executed
-1. As the script executes, Streamlit draws its output live in a browser
-1. Scripts use the Streamlit cache to avoid recomputing expensive functions, so
- updates happen very fast
-1. Every time a user interacts with a widget, your script is re-executed and
- the output value of that widget is set to the new value during that run.
-1. Streamlit apps can contain multiple pages, which are defined in separate
- `.py` files in a `pages` folder.
-
-
diff --git a/data/library/get-started/multipage-apps/create-a-multi-page-app.md b/data/library/get-started/multipage-apps/create-a-multi-page-app.md
deleted file mode 100644
index 6fd4190f9..000000000
--- a/data/library/get-started/multipage-apps/create-a-multi-page-app.md
+++ /dev/null
@@ -1,574 +0,0 @@
----
-title: Create a multipage app
-slug: /library/get-started/multipage-apps/create-a-multipage-app
----
-
-# Create a multipage app
-
-In the [last section](/library/get-started/multipage-apps), we learned what it takes to create multipage apps, including how to define pages, structure and run multipage apps, and navigate between pages in the user interface. If you need a refresher, now is a good time to take a look.
-
-In this guide, let’s put our understanding of multipage apps to use by converting the familiar `streamlit hello` command to a multipage app!
-
-## Motivation
-
-Before Streamlit 1.10.0, the streamlit hello command was a large single-page app. As there was no support for multiple pages, we resorted to splitting the app's content using `st.selectbox` in the sidebar to choose what content to run. The content is comprised of three demos for plotting, mapping, and dataframes.
-
-Here's what the code and single-page app looked like:
-
-
-hello.py (👈 Toggle to expand)
-
-
-```python
-import streamlit as st
-
-def intro():
- import streamlit as st
-
- st.write("# Welcome to Streamlit! 👋")
- st.sidebar.success("Select a demo above.")
-
- st.markdown(
- """
- Streamlit is an open-source app framework built specifically for
- Machine Learning and Data Science projects.
-
- **👈 Select a demo from the dropdown on the left** to see some examples
- of what Streamlit can do!
-
- ### Want to learn more?
-
- - Check out [streamlit.io](https://streamlit.io)
- - Jump into our [documentation](https://docs.streamlit.io)
- - Ask a question in our [community
- forums](https://discuss.streamlit.io)
-
- ### See more complex demos
-
- - Use a neural net to [analyze the Udacity Self-driving Car Image
- Dataset](https://github.com/streamlit/demo-self-driving)
- - Explore a [New York City rideshare dataset](https://github.com/streamlit/demo-uber-nyc-pickups)
- """
- )
-
-def mapping_demo():
- import streamlit as st
- import pandas as pd
- import pydeck as pdk
-
- from urllib.error import URLError
-
- st.markdown(f"# {list(page_names_to_funcs.keys())[2]}")
- st.write(
- """
- This demo shows how to use
-[`st.pydeck_chart`](https://docs.streamlit.io/library/api-reference/charts/st.pydeck_chart)
-to display geospatial data.
-"""
- )
-
- @st.cache_data
- def from_data_file(filename):
- url = (
- "http://raw.githubusercontent.com/streamlit/"
- "example-data/master/hello/v1/%s" % filename
- )
- return pd.read_json(url)
-
- try:
- ALL_LAYERS = {
- "Bike Rentals": pdk.Layer(
- "HexagonLayer",
- data=from_data_file("bike_rental_stats.json"),
- get_position=["lon", "lat"],
- radius=200,
- elevation_scale=4,
- elevation_range=[0, 1000],
- extruded=True,
- ),
- "Bart Stop Exits": pdk.Layer(
- "ScatterplotLayer",
- data=from_data_file("bart_stop_stats.json"),
- get_position=["lon", "lat"],
- get_color=[200, 30, 0, 160],
- get_radius="[exits]",
- radius_scale=0.05,
- ),
- "Bart Stop Names": pdk.Layer(
- "TextLayer",
- data=from_data_file("bart_stop_stats.json"),
- get_position=["lon", "lat"],
- get_text="name",
- get_color=[0, 0, 0, 200],
- get_size=15,
- get_alignment_baseline="'bottom'",
- ),
- "Outbound Flow": pdk.Layer(
- "ArcLayer",
- data=from_data_file("bart_path_stats.json"),
- get_source_position=["lon", "lat"],
- get_target_position=["lon2", "lat2"],
- get_source_color=[200, 30, 0, 160],
- get_target_color=[200, 30, 0, 160],
- auto_highlight=True,
- width_scale=0.0001,
- get_width="outbound",
- width_min_pixels=3,
- width_max_pixels=30,
- ),
- }
- st.sidebar.markdown("### Map Layers")
- selected_layers = [
- layer
- for layer_name, layer in ALL_LAYERS.items()
- if st.sidebar.checkbox(layer_name, True)
- ]
- if selected_layers:
- st.pydeck_chart(
- pdk.Deck(
- map_style="mapbox://styles/mapbox/light-v9",
- initial_view_state={
- "latitude": 37.76,
- "longitude": -122.4,
- "zoom": 11,
- "pitch": 50,
- },
- layers=selected_layers,
- )
- )
- else:
- st.error("Please choose at least one layer above.")
- except URLError as e:
- st.error(
- """
- **This demo requires internet access.**
-
- Connection error: %s
- """
- % e.reason
- )
-
-def plotting_demo():
- import streamlit as st
- import time
- import numpy as np
-
- st.markdown(f'# {list(page_names_to_funcs.keys())[1]}')
- st.write(
- """
- This demo illustrates a combination of plotting and animation with
-Streamlit. We're generating a bunch of random numbers in a loop for around
-5 seconds. Enjoy!
-"""
- )
-
- progress_bar = st.sidebar.progress(0)
- status_text = st.sidebar.empty()
- last_rows = np.random.randn(1, 1)
- chart = st.line_chart(last_rows)
-
- for i in range(1, 101):
- new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0)
- status_text.text("%i%% Complete" % i)
- chart.add_rows(new_rows)
- progress_bar.progress(i)
- last_rows = new_rows
- time.sleep(0.05)
-
- progress_bar.empty()
-
- # Streamlit widgets automatically run the script from top to bottom. Since
- # this button is not connected to any other logic, it just causes a plain
- # rerun.
- st.button("Re-run")
-
-
-def data_frame_demo():
- import streamlit as st
- import pandas as pd
- import altair as alt
-
- from urllib.error import URLError
-
- st.markdown(f"# {list(page_names_to_funcs.keys())[3]}")
- st.write(
- """
- This demo shows how to use `st.write` to visualize Pandas DataFrames.
-
-(Data courtesy of the [UN Data Explorer](http://data.un.org/Explorer.aspx).)
-"""
- )
-
- @st.cache_data
- def get_UN_data():
- AWS_BUCKET_URL = "http://streamlit-demo-data.s3-us-west-2.amazonaws.com"
- df = pd.read_csv(AWS_BUCKET_URL + "/agri.csv.gz")
- return df.set_index("Region")
-
- try:
- df = get_UN_data()
- countries = st.multiselect(
- "Choose countries", list(df.index), ["China", "United States of America"]
- )
- if not countries:
- st.error("Please select at least one country.")
- else:
- data = df.loc[countries]
- data /= 1000000.0
- st.write("### Gross Agricultural Production ($B)", data.sort_index())
-
- data = data.T.reset_index()
- data = pd.melt(data, id_vars=["index"]).rename(
- columns={"index": "year", "value": "Gross Agricultural Product ($B)"}
- )
- chart = (
- alt.Chart(data)
- .mark_area(opacity=0.3)
- .encode(
- x="year:T",
- y=alt.Y("Gross Agricultural Product ($B):Q", stack=None),
- color="Region:N",
- )
- )
- st.altair_chart(chart, use_container_width=True)
- except URLError as e:
- st.error(
- """
- **This demo requires internet access.**
-
- Connection error: %s
- """
- % e.reason
- )
-
-page_names_to_funcs = {
- "—": intro,
- "Plotting Demo": plotting_demo,
- "Mapping Demo": mapping_demo,
- "DataFrame Demo": data_frame_demo
-}
-
-demo_name = st.sidebar.selectbox("Choose a demo", page_names_to_funcs.keys())
-page_names_to_funcs[demo_name]()
-```
-
-
-
-
-
-Notice how large the file is! Each app “page" is written as a function, and the selectbox is used to pick which page to display. As our app grows, maintaining the code requires a lot of additional overhead. Moreover, we’re limited by the `st.selectbox` UI to choose which “page" to run, we cannot customize individual page titles with `st.set_page_config`, and we’re unable to navigate between pages using URLs.
-
-## Convert an existing app into a multipage app
-
-Now that we've identified the limitations of a single-page app, what can we do about it? Armed with our knowledge from the previous section, we can convert the existing app to be a multipage app, of course! At a high level, we need to perform the following steps:
-
-1. Create a new `pages` folder in the same folder where the “entrypoint file" (`hello.py`) lives
-2. Rename our entrypoint file to `Hello.py` , so that the title in the sidebar is capitalized
-3. Create three new files inside of `pages`:
- - `pages/1_📈_Plotting_Demo.py`
- - `pages/2_🌍_Mapping_Demo.py`
- - `pages/3_📊_DataFrame_Demo.py`
-4. Move the contents of the `plotting_demo`, `mapping_demo`, and `data_frame_demo` functions into their corresponding new files from Step 3
-5. Run `streamlit run Hello.py` to view your newly converted multipage app!
-
-Now, let’s walk through each step of the process and view the corresponding changes in code.
-
-## Create the entrypoint file
-
-
-Hello.py
-
-```python
-import streamlit as st
-
-st.set_page_config(
- page_title="Hello",
- page_icon="👋",
-)
-
-st.write("# Welcome to Streamlit! 👋")
-
-st.sidebar.success("Select a demo above.")
-
-st.markdown(
- """
- Streamlit is an open-source app framework built specifically for
- Machine Learning and Data Science projects.
- **👈 Select a demo from the sidebar** to see some examples
- of what Streamlit can do!
- ### Want to learn more?
- - Check out [streamlit.io](https://streamlit.io)
- - Jump into our [documentation](https://docs.streamlit.io)
- - Ask a question in our [community
- forums](https://discuss.streamlit.io)
- ### See more complex demos
- - Use a neural net to [analyze the Udacity Self-driving Car Image
- Dataset](https://github.com/streamlit/demo-self-driving)
- - Explore a [New York City rideshare dataset](https://github.com/streamlit/demo-uber-nyc-pickups)
-"""
-)
-```
-
-
-
-
-We rename our entrypoint file to `Hello.py` , so that the title in the sidebar is capitalized and only the code for the intro page is included. Additionally, we’re able to customize the page title and favicon — as it appears in the browser tab with `st.set_page_config`. We can do so for each of our pages too!
-
-
-
-Notice how the sidebar does not contain page labels as we haven’t created any pages yet.
-
-## Create multiple pages
-
-A few things to remember here:
-
-1. We can change the ordering of pages in our MPA by adding numbers to the beginning of each Python file. If we add a 1 to the front of our file name, Streamlit will put that file first in the list.
-2. The name of each Streamlit app is determined by the file name, so to change the app name you need to change the file name!
-3. We can add some fun to our app by adding emojis to our file names that will render in our Streamlit app.
-4. Each page will have its own URL, defined by the name of the file.
-
-Check out how we do all this below! For each new page, we create a new file inside the pages folder, and add the appropriate demo code into it.
-
-
-
-
-
-pages/1_📈_Plotting_Demo.py
-
-```python
-import streamlit as st
-import time
-import numpy as np
-
-st.set_page_config(page_title="Plotting Demo", page_icon="📈")
-
-st.markdown("# Plotting Demo")
-st.sidebar.header("Plotting Demo")
-st.write(
- """This demo illustrates a combination of plotting and animation with
-Streamlit. We're generating a bunch of random numbers in a loop for around
-5 seconds. Enjoy!"""
-)
-
-progress_bar = st.sidebar.progress(0)
-status_text = st.sidebar.empty()
-last_rows = np.random.randn(1, 1)
-chart = st.line_chart(last_rows)
-
-for i in range(1, 101):
- new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0)
- status_text.text("%i%% Complete" % i)
- chart.add_rows(new_rows)
- progress_bar.progress(i)
- last_rows = new_rows
- time.sleep(0.05)
-
-progress_bar.empty()
-
-# Streamlit widgets automatically run the script from top to bottom. Since
-# this button is not connected to any other logic, it just causes a plain
-# rerun.
-st.button("Re-run")
-```
-
-
-
-
-
-
-pages/2_🌍_Mapping_Demo.py
-
-```python
-import streamlit as st
-import pandas as pd
-import pydeck as pdk
-from urllib.error import URLError
-
-st.set_page_config(page_title="Mapping Demo", page_icon="🌍")
-
-st.markdown("# Mapping Demo")
-st.sidebar.header("Mapping Demo")
-st.write(
- """This demo shows how to use
-[`st.pydeck_chart`](https://docs.streamlit.io/library/api-reference/charts/st.pydeck_chart)
-to display geospatial data."""
-)
-
-
-@st.cache_data
-def from_data_file(filename):
- url = (
- "http://raw.githubusercontent.com/streamlit/"
- "example-data/master/hello/v1/%s" % filename
- )
- return pd.read_json(url)
-
-
-try:
- ALL_LAYERS = {
- "Bike Rentals": pdk.Layer(
- "HexagonLayer",
- data=from_data_file("bike_rental_stats.json"),
- get_position=["lon", "lat"],
- radius=200,
- elevation_scale=4,
- elevation_range=[0, 1000],
- extruded=True,
- ),
- "Bart Stop Exits": pdk.Layer(
- "ScatterplotLayer",
- data=from_data_file("bart_stop_stats.json"),
- get_position=["lon", "lat"],
- get_color=[200, 30, 0, 160],
- get_radius="[exits]",
- radius_scale=0.05,
- ),
- "Bart Stop Names": pdk.Layer(
- "TextLayer",
- data=from_data_file("bart_stop_stats.json"),
- get_position=["lon", "lat"],
- get_text="name",
- get_color=[0, 0, 0, 200],
- get_size=15,
- get_alignment_baseline="'bottom'",
- ),
- "Outbound Flow": pdk.Layer(
- "ArcLayer",
- data=from_data_file("bart_path_stats.json"),
- get_source_position=["lon", "lat"],
- get_target_position=["lon2", "lat2"],
- get_source_color=[200, 30, 0, 160],
- get_target_color=[200, 30, 0, 160],
- auto_highlight=True,
- width_scale=0.0001,
- get_width="outbound",
- width_min_pixels=3,
- width_max_pixels=30,
- ),
- }
- st.sidebar.markdown("### Map Layers")
- selected_layers = [
- layer
- for layer_name, layer in ALL_LAYERS.items()
- if st.sidebar.checkbox(layer_name, True)
- ]
- if selected_layers:
- st.pydeck_chart(
- pdk.Deck(
- map_style="mapbox://styles/mapbox/light-v9",
- initial_view_state={
- "latitude": 37.76,
- "longitude": -122.4,
- "zoom": 11,
- "pitch": 50,
- },
- layers=selected_layers,
- )
- )
- else:
- st.error("Please choose at least one layer above.")
-except URLError as e:
- st.error(
- """
- **This demo requires internet access.**
- Connection error: %s
- """
- % e.reason
- )
-```
-
-
-
-
-
-
-pages/3_📊_DataFrame_Demo.py
-
-```python
-import streamlit as st
-import pandas as pd
-import altair as alt
-from urllib.error import URLError
-
-st.set_page_config(page_title="DataFrame Demo", page_icon="📊")
-
-st.markdown("# DataFrame Demo")
-st.sidebar.header("DataFrame Demo")
-st.write(
- """This demo shows how to use `st.write` to visualize Pandas DataFrames.
-(Data courtesy of the [UN Data Explorer](http://data.un.org/Explorer.aspx).)"""
-)
-
-
-@st.cache_data
-def get_UN_data():
- AWS_BUCKET_URL = "http://streamlit-demo-data.s3-us-west-2.amazonaws.com"
- df = pd.read_csv(AWS_BUCKET_URL + "/agri.csv.gz")
- return df.set_index("Region")
-
-
-try:
- df = get_UN_data()
- countries = st.multiselect(
- "Choose countries", list(df.index), ["China", "United States of America"]
- )
- if not countries:
- st.error("Please select at least one country.")
- else:
- data = df.loc[countries]
- data /= 1000000.0
- st.write("### Gross Agricultural Production ($B)", data.sort_index())
-
- data = data.T.reset_index()
- data = pd.melt(data, id_vars=["index"]).rename(
- columns={"index": "year", "value": "Gross Agricultural Product ($B)"}
- )
- chart = (
- alt.Chart(data)
- .mark_area(opacity=0.3)
- .encode(
- x="year:T",
- y=alt.Y("Gross Agricultural Product ($B):Q", stack=None),
- color="Region:N",
- )
- )
- st.altair_chart(chart, use_container_width=True)
-except URLError as e:
- st.error(
- """
- **This demo requires internet access.**
- Connection error: %s
- """
- % e.reason
- )
-```
-
-
-
-
-
-With our additional pages created, we can now put it all together in the final step below.
-
-## Run the multipage app
-
-To run your newly converted multipage app, run:
-
-```bash
-streamlit run Hello.py
-```
-
-That’s it! The `Hello.py` script now corresponds to the main page of your app, and other scripts that Streamlit finds in the pages folder will also be present in the new page selector that appears in the sidebar.
-
-
-
-## Next steps
-
-Congratulations! 🎉 If you've read this far, chances are you've learned to create both single-page and multipage apps. Where you go from here is entirely up to your creativity! We’re excited to see what you’ll build now that adding additional pages to your apps is easier than ever. Try adding more pages to the app we've just built as an exercise. Also, stop by the forum to show off your multipage apps with the Streamlit community! 🎈
-
-Here are a few resources to help you get started:
-
-- Deploy your app for free on Streamlit's [Community Cloud](/streamlit-community-cloud).
-- Post a question or share your multipage app on our [community forum](https://discuss.streamlit.io/c/streamlit-examples/9).
-- Check out our documentation on [multipage apps](/library/get-started/multipage-apps).
-- Read through [Advanced features](/library/advanced-features) for things like caching, theming, and adding statefulness to apps.
-- Browse our [API reference](/library/api-reference/) for examples of every Streamlit command.
diff --git a/data/library/get-started/multipage-apps/index.md b/data/library/get-started/multipage-apps/index.md
deleted file mode 100644
index 94419601e..000000000
--- a/data/library/get-started/multipage-apps/index.md
+++ /dev/null
@@ -1,139 +0,0 @@
----
-title: Multipage apps
-slug: /library/get-started/multipage-apps
----
-
-# Multipage apps
-
-As apps grow large, it becomes useful to organize them into multiple pages. This makes the app easier to manage as a developer and easier to navigate as a user. Streamlit provides a frictionless way to create multipage apps. Pages are automatically shown in a nice navigation widget inside the app sidebar, and clicking on a page will navigate to the page without reloading the frontend — making app browsing incredibly fast!
-
-We created a "single-page app" to explore a public Uber dataset for pickups and drop-offs in New York City on the [previous page](/library/get-started/create-an-app). In this guide, let’s learn how to create multipage apps. Once we have a solid foundation on what it takes to create multipage apps, let’s build one for ourselves in the [next section](/library/get-started/multipage-apps/create-a-multipage-app)!
-
-## Structuring multipage apps
-
-Let's understand what it takes to create multipage apps — including how to define pages, structure and run multipage apps, and navigate between pages in the user interface. Once you've understood the basics, you can jump right into the [next section](/library/get-started/multipage-apps/create-a-multipage-app) to convert the familiar `streamlit hello` command into a multipage app!
-
-## Run a multipage app
-
-Running a multipage app is identical to running a single-page app. The command to run a multipage app is:
-
-```python
-streamlit run [entrypoint file]
-```
-
-The "entrypoint file" is the first page the app will show to the user. Once you have added pages to your app, the entrypoint file appears as the top-most page in the sidebar. You can think of the entrypoint file as your app's "main page". For example, say your entrypoint file is `Home.py`. Then, to run your app, you can run `streamlit run Home.py`. This will start your app and execute the code in `Home.py`.
-
-## Adding pages
-
-Once you've created your entrypoint file, you can add pages by creating `.py` files in a `pages/` directory relative to your entrypoint file. For example, if your entrypoint file is `Home.py`, then you can create a `pages/About.py` file to define the "About" page. Here's a valid directory structure for a multipage app:
-
-```
-Home.py # This is the file you run with "streamlit run"
-└─── pages/
- └─── About.py # This is a page
- └─── 2_Page_two.py # This is another page
- └─── 3_😎_three.py # So is this
-```
-
-
-
-When adding emojis to filenames, it’s best practice to include a numbered-prefix to make autocompletion in your terminal easier. Terminal-autocomplete can get confused by unicode (which is how emojis are represented).
-
-
-
-Pages are defined as `.py` files in a `pages/` directory. The filenames of pages are transformed to page names in the sidebar based on the the rules in the [section below](#how-pages-are-labeled-and-sorted-in-the-ui). For example, the `About.py` file will appear as "About" in the sidebar, `2_Page_two.py` appears as "Page two", and `3_😎_three.py` appears as “😎 three":
-
-
-
-Only `.py` files in the `pages/` directory will be loaded as pages. Streamlit ignores all other files in the `pages/` directory and subdirectories.
-
-## How pages are labeled and sorted in the UI
-
-Page labels in the sidebar UI are generated from filenames. They may differ from the page title set in [`st.set_page_config`](/library/api-reference/utilities/st.set_page_config). Let's learn what constitutes a valid filename for a page, how pages are displayed in the sidebar, and how pages are sorted.
-
-### Valid filenames for pages
-
-Filenames are composed of four different parts:
-
-1. A `number` — if the file is prefixed with a number.
-2. A separator — could be `_`, `-`, space, or any combination thereof.
-3. A `label` — which is everything up to, but not including, `.py`.
-4. The extension — which is always `.py`.
-
-### How pages are displayed in the sidebar
-
-What is displayed in the sidebar is the `label` part of the filename:
-
-- If there's no `label`, Streamlit uses the `number` as the label.
-- In the UI, Streamlit beautifies the `label` by replacing `_` with space.
-
-### How pages are sorted in the sidebar
-
-Sorting considers numbers in the filename to be actual numbers (_integers_):
-
-- Files that have a `number` appear before files without a `number`.
-- Files are sorted based on the `number` (if any), followed by the `title` (if any).
-- When files are sorted, Streamlit treats the `number` as an actual number rather than a string. So `03` is the same as `3`.
-
-This table shows examples of filenames and their corresponding labels, sorted by the order in which they appear in the sidebar.
-
-**Examples**:
-
-| **Filename** | **Rendered label** |
-| :------------------------ | :----------------- |
-| `1 - first page.py` | first page |
-| `12 monkeys.py` | monkeys |
-| `123.py` | 123 |
-| `123_hello_dear_world.py` | hello dear world |
-| `_12 monkeys.py` | 12 monkeys |
-
-
-
-Emojis can be used to make your page names more fun! For example, a file named `🏠_Home.py` will create a page titled "🏠 Home" in the sidebar.
-
-
-
-## Navigating between pages
-
-Pages are automatically shown in a nice navigation UI inside the app's sidebar. When you click on a page in the sidebar UI, Streamlit navigates to that page without reloading the entire frontend — making app browsing incredibly fast!
-
-You can also navigate between pages using URLs. Pages have their own URLs, defined by the file's `label`. When multiple files have the same `label`, Streamlit picks the first one (based on the ordering [described above](/library/get-started/multipage-apps#how-pages-are-sorted-in-the-sidebar)). Users can view a specific page by visiting the page's URL.
-
-If a user tries to access a URL for a page that does not exist, they will see a modal like the one below, saying the user has requested a page that was not found in the app’s pages/ directory.
-
-
-
-## Notes
-
-- Pages support [magic commands](https://docs.streamlit.io/library/api-reference/write-magic/magic).
-- Pages support run-on-save. Additionally, when you save a page, this causes a rerun for users currently viewing that exact page.
-- Adding or deleting a page causes the UI to update immediately.
-- Updating pages in the sidebar does not rerun the script.
-- `st.set_page_config` works at the page level. When you set a title or favicon using [st.set_page_config](/library/api-reference/utilities/st.set_page_config), this applies to the current page only.
-- Pages share the same Python modules globally:
-
- ```python
- # page1.py
- import foo
- foo.hello = 123
-
- # page2.py
- import foo
- st.write(foo.hello) # If page1 already executed, this should write 123
- ```
-
-- Pages share the same [st.session_state](https://docs.streamlit.io/library/advanced-features/session-state):
-
- ```python
- # page1.py
- import streamlit as st
- if "shared" not in st.session_state:
- st.session_state["shared"] = True
-
- # page2.py
- import streamlit as st
- st.write(st.session_state["shared"])
- # If page1 already executed, this should write True
- ```
-
-You now have a solid understanding of multipage apps. You've learned how to structure apps, define pages, and navigate between pages in the user interface. It's time to [create your first multipage app](/library/get-started/multipage-apps/create-a-multipage-app)! 🥳
diff --git a/data/library/index.md b/data/library/index.md
deleted file mode 100644
index 9b1de55b1..000000000
--- a/data/library/index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: Streamlit Library
-slug: /library
----
-
-# Streamlit Library
-
-
diff --git a/data/streamlit-cloud/deploy-your-app/app-dependencies.md b/data/streamlit-cloud/deploy-your-app/app-dependencies.md
deleted file mode 100644
index 347cfd831..000000000
--- a/data/streamlit-cloud/deploy-your-app/app-dependencies.md
+++ /dev/null
@@ -1,111 +0,0 @@
----
-title: App dependencies
-slug: /streamlit-community-cloud/deploy-your-app/app-dependencies
----
-
-# App dependencies
-
-The main reason that apps fail to build properly is because Streamlit Community Cloud can't find your dependencies! There are two kinds of dependencies your app might have: Python dependencies and external dependencies. Python dependencies are other Python packages (just like Streamlit!) that you `import` into you script. External dependencies are less common, but they include any other software your script needs to function properly. Since Streamlit Community Cloud runs on Linux, these will be Linux dependencies installed with `apt-get` outside the Python environment.
-
-For your dependencies to be installed correctly, make sure you:
-
-1. Add a [requirements file](#add-python-dependencies) for Python dependencies.
-2. (optional) Add a `packages.txt` file to manage any external dependencies.
-
-
-
-Python requirements files should be placed either in the root of your repository or in the same
-directory as your Streamlit app.
-
-
-
-## Add Python dependencies
-
-With each `import` statement in your script, you are bringing in a Python dependency. You need to tell Streamlit Community Cloud how to install those depencies through a Python package manager. We recommend using a `requirements.txt` which is based on `pip`.
-
-You should _not_ include built-in Python libraries like `math` or `random` in your `requirements.txt` file. These are a part of Python and aren't installed separately. Also, Streamlit Community Cloud has `streamlit` installed by default. You don't strictly need to include `streamlit` unless you want to pin or restrict the version. If you deploy an app without a `requirements.txt` file, your app will run in an environment with just `streamlit` (and its dependencies) installed.
-
-If you have a script like the following, no extra dependencies would be needed since `pandas` and `numpy` are installed as direct dependencies of `streamlit`. Similarly, `math` and `random` are built into Python.
-
-```python
-import streamlit as st
-import pandas as pd
-import numpy as np
-import math
-import random
-
-st.write('Hi!')
-```
-
-However, a valid `requirements.txt` file would be:
-
-```none
-streamlit
-pandas
-numpy
-```
-
-Alternatively, if you needed to specify certain versions, another valid example would be:
-
-```none
-streamlit==1.24.1
-pandas>2.0
-numpy<=1.25.1
-```
-
-In the above example, `streamlit` is pinned to version `1.24.1`, `pandas` must be strictly greater than version 2.0, and `numpy` must be at-or-below version 1.25.1. Each line in your `requirements.txt` file is effectively what you would like to `pip install` into your cloud environment.
-
-
-
-We recommend that you use the latest version of Streamlit to ensure full Streamlit Community Cloud functionality. Be sure to take note of Streamlit's [current requirements](https://github.com/streamlit/streamlit/blob/develop/lib/setup.py) for package compatibility when planning your environment, especially `protobuf>=3.20,<5`.
-
-
-
-If you pin `streamlit` below 1.20.0, you may experience unexpected results if you've pinned any dependencies of `altair`. If `streamlit` is installed below version 1.20.0, `altair<5` will be reinstalled on top of your evironment for compatibility reasons. When this happens all of altair's dependecies will be updated.
-
-### Other Python package managers
-
-There are other Python package managers besides `pip`. If you want to consider alternatives to using a `requirements.txt` file, Streamlit Community Cloud will look for other Python dependency managers to use in the order below. Streamlit will stop and install the first dependency file found.
-
-
-
-
-
-You should only use one requirements file for your app. If you include more than one (e.g. `requirements.txt` and `Pipfile`), only the first file encountered will be used as described above. Additionally, Streamlit will first look in the directory of your Streamlit app; however, if no requirements file is found, Streamlit will then look at the root of the repo.
-
-
-
-## apt-get dependencies
-
-For many apps, a `packages.txt` file is not required. However, if your script requires any software to be installed that is not a Python package, then you will need a `packages.txt` file. Streamlit Community Cloud is built on Debian Linux. Anything you would like to `apt-get install` needs to go in your `packages.txt` file.
-
-If `packages.txt` exists in the root directory of your repository we automatically detect it, parse it, and install the listed packages. You can read more about apt-get in Linux documentation.
-
-Add **apt-get** dependencies to `packages.txt` — one package name per line. For example, mysqlclient is a Python package which requires additional software be installed to function. A valid `packages.txt` file to enable `mysqlclient` would be:
-
-```bash
- build-essential
- pkg-config
- default-libmysqlclient-dev
-```
diff --git a/data/streamlit-cloud/deploy-your-app/index.md b/data/streamlit-cloud/deploy-your-app/index.md
deleted file mode 100644
index 2b249219d..000000000
--- a/data/streamlit-cloud/deploy-your-app/index.md
+++ /dev/null
@@ -1,132 +0,0 @@
----
-title: Deploy your app
-slug: /streamlit-community-cloud/deploy-your-app
----
-
-# Deploy your app
-
-Streamlit Community Cloud lets you deploy your apps in just one click, and most apps will deploy in only a few minutes. If you don't have an app ready to deploy, fork or clone one from our App gallery — you can find apps for machine learning, data visualization, data exploration, A/B testing and more.
-
-
-
-If you want to deploy your app on a different cloud service, check out the [Deploy Streamlit apps](/knowledge-base/tutorials/deploy) article in our Knowledge Base.
-
-
-
-## Add your app to GitHub
-
-Streamlit Community Cloud launches apps directly from your GitHub repo, so your app code and dependencies need to be on GitHub before you try to deploy your app. For more information on how to specify dependencies, see [App dependencies](/streamlit-community-cloud/deploy-your-app/app-dependencies).
-
-Your directory structure should look similar to this:
-
-```
-your-repository/
-├── your_app.py
-└── requirements.txt
-```
-
-If you are including any custom [Configuration](/library/advanced-features/configuration) or [Theming](/library/advanced-features/theming), make sure your config file is saved relative to the root of your repo. Within your repo, your config file should be named `.streamlit/config.toml`.
-
-```
-your-repository/
-├── .streamlit/
-│ └── config.toml
-├── your_app.py
-└── requirements.txt
-```
-
-
-
- Although you can deploy multiple apps from the same repository, there can be only one configuration file.
-
-
-
-## Deploy your app
-
-1. From your workspace at share.streamlit.io, click "**New app**" from the upper-right corner of your workspace.
-
- 
-
-2. Fill in your repo, branch, and file path. As a shortcut, you can also click "**Paste GitHub URL**" to paste a link directly to `your_app.py` on GitHub.
-
- An app URL with a random hash is prefilled but you can change this to a custom subdomain instead. In the example below, the app would be deployed to `https://red-balloon.streamlit.app/`. You can always change your subdomain later. See more about [Custom subdomains](#custom-subdomains) at the end of this page.
-
- 
-
-## Advanced settings for deployment
-
-3. (Optional) If you are connecting to a data source or want to specify the Python version for your app, you can do that by clicking "**Advanced settings**" before you deploy the app. Learn more about [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
- 
-
-
-
-Streamlit Community Cloud supports Python 3.8 - Python 3.11, and defaults to version 3.9. You can select a version of your choice from the "Python version" dropdown in the "Advanced settings" modal.
-
-
-
-## Watch your app launch
-
-Your app is now deploying and you can watch while it launches. Most apps take only a couple of minutes to deploy, but if your app has a lot of dependencies it may take longer to deploy the first time. After the initial deployment, any change that does not touch your dependencies should show up immediately.
-
-
-
-
-
-The Streamlit Community Cloud logs on the right hand side of your app are only viewable to users with developer access to your repository. These logs help you debug any issues with the app. Learn more about [Streamlit Community Cloud logs](/streamlit-community-cloud/manage-your-app#streamlit-community-cloud-logs).
-
-
-
-## Your app URL
-
-That's it — you're done! Your app now has a unique subdomain URL that you can share with others. Read more about how to [Share your app](/streamlit-community-cloud/share-your-app) with viewers.
-
-### Unique subdomains
-
-If the "**Custom subdomain (optional)**" field is blank when you deploy your app, a URL is assigned following a structure based on your GitHub repo. The URL begins with your GitHub username or organization owning your repo, followed by your repo name, app path, and a short hash. If you deploy from a branch other than `main` or `master`, the URL also includes the branch name.
-
-```bash
-https://[GitHub username or organization]-[repo name]-[app path]-[branch name]-[short hash].streamlit.app
-```
-
-For example, this is an app deployed from the `streamlit` organization. The repo is `demo-self-driving` and the app name is `streamlit_app.py` in the root directory. The branch name is `master` and therefore not included.
-
-```bash
-https://streamlit-demo-self-driving-streamlit-app-8jya0g.streamlit.app
-```
-
-### Custom subdomains
-
-Setting a custom subdomain makes it much easier to share your app since you can choose something memorable. Whether you set a custom subdomain during deployment or later, your app's URL will appear as:
-
-```bash
-https://.streamlit.app
-```
-
-To view or customize your app subdomain from the dashboard:
-
-1. Click the overflow icon (more_vert) to the app's right and select "**Settings**".
-
-
-
-
-
-2. View the "**General**" tab in the App settings modal. Your app's unique subdomain will appear here.
-
-
-
-
-
-3. Pick a custom subdomain between 6 and 63 characters in length for your app's URL and hit "**Save**".
-
-
-
-
-
-It's that simple! You can then access your app by visiting your customized URL 🎉.
-
-If a custom subdomain is not available (e.g. because it's already taken), you'll see an error message like this:
-
-
-
-
diff --git a/data/streamlit-cloud/deploy-your-app/secrets-management.md b/data/streamlit-cloud/deploy-your-app/secrets-management.md
deleted file mode 100644
index 57a9d5d54..000000000
--- a/data/streamlit-cloud/deploy-your-app/secrets-management.md
+++ /dev/null
@@ -1,117 +0,0 @@
----
-title: Secrets management
-slug: /streamlit-community-cloud/deploy-your-app/secrets-management
----
-
-# Secrets management
-
-## Introduction
-
-If you are [connecting to data sources](/knowledge-base/tutorials/databases), you will likely need to handle credentials or secrets. It's generally considered bad practice to store unencrypted secrets in a git repository. If your application needs access to sensitive credentials the recommended solution is to store those credentials in a file that is not committed to the repository and to pass them as environment variables.
-
-Secrets management allows you to store secrets securely and access them in your Streamlit app as environment variables.
-
-## How to use Secrets Management
-
-### Deploy an app and set up secrets
-
-1. From your worksapce at share.streamlit.io, click "**New app**".
-2. Fill out your app's information and click "**Advanced settings...**"
-
- 
-
-3. A modal will appear with an input box for your secrets.
-
- 
-
-4. Provide your secrets in the "Secrets" field using TOML format. For example:
-
- ```toml
- # Everything in this section will be available as an environment variable
- db_username = "Jane"
- db_password = "12345qwerty"
-
- # You can also add other sections if you like.
- # The contents of sections as shown below will not become environment
- # variables, but they'll be easily accessible from within Streamlit anyway
- # as we show later in this doc.
- [my_cool_secrets]
- things_i_like = ["Streamlit", "Python"]
- ```
-
-### Use secrets in your app
-
-Access your secrets as environment variables or by querying the `st.secrets` dict. For example, if you enter the secrets from the section above, the code below shows you how you can access them within your Streamlit app.
-
-```python
-import streamlit as st
-import os
-
-# Everything is accessible via the st.secrets dict:
-st.write("DB username:", st.secrets["db_username"])
-st.write("DB password:", st.secrets["db_password"])
-st.write("My cool secrets:", st.secrets["my_cool_secrets"]["things_i_like"])
-
-# And the root-level secrets are also accessible as environment variables:
-st.write(
- "Has environment variables been set:",
- os.environ["db_username"] == st.secrets["db_username"],
-)
-```
-
-
-
-You can access `st.secrets` via attribute notation (e.g. `st.secrets.key`) or key notation (e.g. `st.secrets["key"]`) — just like [`st.session_state`](/library/api-reference/session-state).
-
-
-
-You can even use TOML sections to compactly pass multiple secrets as a single attribute.
-
-Consider the following secrets:
-
-```toml
-[db_credentials]
-username = "my_username"
-password = "my_password"
-```
-
-Rather than passing each secret as attributes in a function, you can more compactly pass the section to achieve the same result. You can use Python's unpacking notation like the following example which uses the secrets above:
-
-```python
-# Verbose version
-my_db.connect(username=st.secrets.db_credentials.username, password=st.secrets.db_credentials.password)
-
-# Far more compact version!
-my_db.connect(**st.secrets.db_credentials)
-```
-
-### Edit your app's secrets
-
-If you need to add or edit your secrets for an app that is already deployed, you can accesss advanced setting from your admin panel.
-
-1. Go to share.streamlit.io.
-2. Click the overflow menu icon (more_vert) for your app.
-3. Click "**Settings**".
- 
-3. A modal will appear. Click "**Secrets**" on the left.
- 
-4. After you edit your secrets, click "**Save**". It might take a minute for the update to be propagated to your app, but the new values will be reflected when the app re-runs.
-
-### Develop locally with secrets
-
-When developing your app locally, add a file called `secrets.toml` in a folder called `.streamlit` at the root of your app repo, and copy/paste your secrets into that file. Further instructions are available in the Streamlit library [Secrets management](/library/advanced-features/secrets-management) documentation.
-
-
-
-Be sure to add this file to your `.gitignore` so you don't commit your secrets!
-
-
-
-```bash
-your-LOCAL-repository/
-├── .streamlit/
-│ ├── config.toml
-│ └── secrets.toml # Make sure to gitignore this!
-├── your_app.py
-└── requirements.txt
-```
diff --git a/data/streamlit-cloud/get-started/connect-github.md b/data/streamlit-cloud/get-started/connect-github.md
deleted file mode 100644
index fe94d533c..000000000
--- a/data/streamlit-cloud/get-started/connect-github.md
+++ /dev/null
@@ -1,74 +0,0 @@
----
-title: Connect your GitHub account
-slug: /streamlit-community-cloud/get-started/connect-your-github-account
----
-
-# Connect your GitHub account
-
-Connecting GitHub to your Streamlit Community Cloud account allows you to deploy apps directly from the files you store in your repos. It also lets the system check for updates to those files and automatically update your app. There are two stages to this authorization: the first happens when you connect your account for the first time and the second happens when you deploy your first app.
-
-Everyone is prompted to connect GitHub when they create an account. If you need to connect GitHub to an existing primary identity, see [Manage your GitHub connection](/streamlit-community-cloud/manage-your-account/manage-your-github-connection).
-
-This page contains additional information about the authorization needed to connect GitHub. If you have just created your account, you are free to skip ahead and [Explore your workspace](/streamlit-community-cloud/get-started/explore-your-workspace). GitHub's authorization prompts occur automatically as needed.
-
-## Authorize your GitHub account
-
-There are two different authorization prompts to grant access between Streamlit and your GitHub account. The first authorization—"Authorize Streamlit"—happens when you connect your GitHub account to Streamlit. The second authorization—"Streamlit is requesting additional permissions"—happens when you deploy your first app. You must click "**Authorize streamlit**" on both. If you are a member of any GitHub organizations, read below to understand the extras steps to [authorize an organization](#organization-access). Questions about GitHub permissions? Read some frequently asked questions about our [GitHub integration](/streamlit-community-cloud/troubleshooting#github-integration).
-
-
-
-
-
-You must have **admin** permissions to your repo in order to deploy apps. If you don't have admin access, talk to the repo's owner or reach out to us on the Community forum.
-
-
-
-## Organization access
-
-If you are working in a repository that is owned by an organization, authorization must be granted by that organization. If you are an owner or member of a GitHub organization when you connect your GitHub account, your authorization prompts will include an extra section labeled "Organization access".
-
-### Organizations you own
-
-For any organization you own, if authorization has not been previously granted or denied you can click "**Grant**" before you click "**Authorize streamlit**".
-
-
-
-### Organizations owned by others
-
-For an organization you don't own, if authorization has not been previously granted or denied you can click "**Request**" before you click "**Authorize streamlit**".
-
-
-
-
-
-### Previous or pending authorization
-
-If someone has already started the process of authorizing Streamlit for your organization, different options and statuses will display accordingly.
-
-#### Approved access
-
-If an organization has already granted Streamlit access, a green check is shown.
-
-
-
-
-
-#### Pending access
-
-If a request has been previously sent but not yet approved, a pending status shows.
-
-
-
-
-
-#### Denied access
-
-If a request has been previously sent and denied, no option to grant or request access is shown. In this case, the organization owner will need to authorize Streamlit from GitHub. See GitHub's documentation on OAuth apps and organizations.
-
-
-
-
-
-## What's next?
-
-Now that you have your account you can [Explore your workspace](/streamlit-community-cloud/get-started/explore-your-workspace). Or if you're ready to go, jump right in and [Deploy your app](/streamlit-community-cloud/deploy-your-app).
diff --git a/data/streamlit-cloud/get-started/create-your-account.md b/data/streamlit-cloud/get-started/create-your-account.md
deleted file mode 100644
index 1d8384b72..000000000
--- a/data/streamlit-cloud/get-started/create-your-account.md
+++ /dev/null
@@ -1,121 +0,0 @@
----
-title: Create your account
-slug: /streamlit-community-cloud/get-started/create-your-account
----
-
-# Create your account
-
-Before you can start deploying apps for the world to see, you need to sign up for your Streamlit Community Cloud account.
-
-
-
-Streamlit Community Cloud accounts have two underlying identities: primary and source control. Your primary identity is used for viewing analytics as well as viewing permissions. Your source-control identity is used for deploying and managing apps.
-
-## Sign up
-
-Although you can begin the sign-up process with GitHub, we recommend starting with Google or email in order to have a complete account from the start.
-* [Step 1: Primary identity](#step-1-primary-identity) (Google or email)
-* [Step 2: Source control](#step-2-source-control) (GitHub)
-* [Step 3: Set up your account](#step-3-set-up-your-account)
-
-### Step 1: Primary identity
-
-Your primary identity is associated to an email. You can sign in through Google or through single-use, emailed links which are valid for 15 minutes once requested.
-
-If you're sharing a private app, you will assign viewing permission by email. Therefore, your app's users will need to sign in with either Google or emailed links.
-
-#### Primary identity option 1: Google
-
-1. Go to share.streamlit.io/signup.
-2. Click "**Continute with Google**".
-
-
-
-
-
-3. Enter your Google credentials and click "**Next**".
-
-
-
-
-
-4. If you will be deploying or managing any apps, click "**Connect GitHub account**" and proceed to [Step 2: Source Control](/streamlit-community-cloud/get-started/create-your-account#step-2-source-control). If you are only going to be viewing apps and will not be using GitHub, you can click "**Skip this step**" and proceed to [Step 3: Set up your account](#step-3-set-up-your-account).
-
-
-
-
-
-#### Primary identity option 2: email
-
-1. Go to share.streamlit.io/signup.
-2. Enter your email address and click "**Continute with email**".
-
-
-
-
-
-3. A confirmation screen will display, telling you to check your email.
-
-
-
-
-
-4. Check your inbox for an email with the subject "Sign in to Streamlit Cloud". Click the link to sign in.
-
-
-
-
-
-5. If you will be deploying or managing any apps, click "**Connect GitHub account**" and proceed to [Step 2: Source control](/streamlit-community-cloud/get-started/create-your-account#step-2-source-control). If you are only going to be viewing apps and will not be using GitHub, you can click "**Skip this step**" and proceed to [Step 3: Set up your account](#step-3-set-up-your-account).
-
-
-
-
-
-### Step 2: Source control
-
-Streamlit Community Cloud is integreated with GitHub for source control. If you begin your sign-up process with GitHub, you will not be directly prompted to create a primary identity. However, you can attach a Google account later.
-
-There are two different authorization requests to completely [Connect your GitHub account](/streamlit-community-cloud/get-started/connect-your-github-account). You will encounter the first authorization request when you begin connecting your GitHub account. A second authorization is needed the first time you deploy an app. If you will be deploying or managing any apps from a GitHub organization, your authorization requests will include additional options to allow [Organization access](/streamlit-community-cloud/get-started/connect-github#organization-access).
-
-1. After completing [Step 1: Primary identity](#step-1-primary-identity) or after clicking "**Continue with GitHub**" from the sign-up page, enter your GitHub credentials and click "**Sign in**".
-
-
-
-
-
-2. Click "**Authorize streamlit**".
-
-
-
-
-
-3. Continue to Step 3: Set up your account
-
-### Step 3: Set up your account
-
-As a final step to account creation, please tell us about yourself and your experience with Streamlit. This is also when you can read and acknowledge our Terms of use and Privacy notice. The email you provide in this survey is not used as your account email.
-
-1. Fill in your information and click "**Continue**" at the bottom of the screen.
-
-
-
-
-
-2. You will be taken to your workspace.
-
-
-
-
-
-### Finish up
-
-Congratulations on creating your Streamlit Community Cloud account! A warning icon (warning) next to "**Settings**" in the upper-right corner is expected; this indicates one of three things:
-
-1. You created a primary identity and skipped connecting GitHub.
-2. You started with GitHub and did not create a primary identity.
-3. You created both a primary identity and connected GitHub, but the second authorization for GitHub is still pending. You will be prompted with the second authorization when you deploy your first app.
-
-## What's next?
-
-Now that you have your account you can [Explore your workspace](/streamlit-community-cloud/get-started/explore-your-workspace). Or if you're ready to go, jump right in and [Deploy your app](/streamlit-community-cloud/deploy-your-app).
diff --git a/data/streamlit-cloud/get-started/explore-your-workspace.md b/data/streamlit-cloud/get-started/explore-your-workspace.md
deleted file mode 100644
index 4c79ebf69..000000000
--- a/data/streamlit-cloud/get-started/explore-your-workspace.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: Explore your workspace
-slug: /streamlit-community-cloud/get-started/explore-your-workspace
----
-
-# Explore your workspace
-
-If you just [created your account](/streamlit-community-cloud/get-started/create-your-account), congrats! You are now logged in and ready to go. If you are joining someone else's workspace you may already see apps populated in your workspace. If not, then you need to deploy an app! Check out our next section on how to [Deploy your app](/streamlit-community-cloud/deploy-your-app). If you need an app to deploy, check out our App gallery which includes apps for machine learning, data science, and business use cases.
-
-
-
-You may also find that you already have access to multiple Streamlit Community Cloud workspaces. Streamlit Community Cloud automatically groups your apps according to the corresponding GitHub repository's owner or organzation. In the upper-right corner you can see the workspaces you have access to. If apps have already been deployed from any of your repositories, then you will see those apps when you select the associated workspace in the upper-right corner. Learn more about how to [Manage your app from your workspace](/streamlit-community-cloud/manage-your-app#manage-your-app-from-your-workspace).
-
-
-
-## Invite other developers to your workspace
-
-Inviting other developers is simple, just invite them to your GitHub repository so that you can code on apps together, and then have them log in to share.streamlit.io/signup. Read more about connecting to a GitHub organization in [Organization access](/streamlit-community-cloud/get-started/connect-your-github-account#organization-access).
-
-Streamlit Community Cloud inherits developer permissions from GitHub so when others sign in, they will automatically see the workspaces they share with you. From there you can all deploy, manage, and share apps together.
-
-
-
-Once a user is added to a repository on GitHub, it will take at most 15 minutes before they can deploy the app on Cloud. If a user is removed from a repository on GitHub, it will take at most 15 minutes before their permissions to manage the app from that repository are revoked.
-
-
-
-And remember, whenever anyone on the team updates the code on GitHub, the app will also automatically update for you!
diff --git a/data/streamlit-cloud/get-started/index.md b/data/streamlit-cloud/get-started/index.md
deleted file mode 100644
index 3bd91ee5e..000000000
--- a/data/streamlit-cloud/get-started/index.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: Get started
-slug: /streamlit-community-cloud/get-started
----
-
-# Get started
-
-Welcome to Streamlit Community Cloud, where you can share your Streamlit apps with the world! Whether you've already created your first Streamlit app or you're just getting started, you're in ther right place.
-
-First things first, you need to create your Streamlit Community Cloud account to start deploying apps.
-
-
-
-
-
-
-
-If you're looking for help to build your first Streamlit app, read our [Get started](/library/get-started) docs for the Streamlit library. If you want to fork an app and start with an example, check out our App gallery. Either way, it only takes a few minutes to create your first app.
diff --git a/data/streamlit-cloud/get-started/quickstart.md b/data/streamlit-cloud/get-started/quickstart.md
deleted file mode 100644
index 5f613e436..000000000
--- a/data/streamlit-cloud/get-started/quickstart.md
+++ /dev/null
@@ -1,97 +0,0 @@
----
-title: Quickstart
-slug: /streamlit-community-cloud/get-started/quickstart
----
-
-# Quickstart
-
-This is a concise set of steps to create your Streamlit Community Cloud account and deploy a sample app. For other options and complete explanations, start with [Create your account](/streamlit-community-cloud/get-started/create-your-account).
-
-You will be signing in to your Google and GitHub accounts during this process. If you do not already have these accounts, you can create them before you begin. If you do not want to use a Google account, you can [create your account with any email](/streamlit-community-cloud/get-started/create-your-account#primary-identity-option-2-email).
-
-## Sign up
-
-1. Go to share.streamlit.io/signup.
-2. Click "**Continue with Google**".
-
-
-
-
-
-3. Enter your Google credentials and follow Google's authentication prompts.
-4. After authenticating with Google, click "**Connect GitHub account**".
-
-
-
-
-
-5. Enter your GitHub credentials and follow GitHub's authentication prompts.
-6. Click "**Authorize streamlit**".
-
-
-
-
-
-7. To finish, fill in your information and click "**Continue**" at the bottom of the screen.
-
-
-
-
-
-8. You will be taken to your Streamlit workspace. If you see a warning icon (warning) next to "**Settings**" in the upper-right corner, this will be addressed in the next steps.
-
-
-
-
-
-## Fork a sample app
-
-9. Click the down arrow (expand_more) to expand the options under "**New App**".
-
-
-
-
-
-10. Click "**Create from sample app template**".
-
-
-
-
-
-11. You will be prompted that "Streamlit is requesting additional permissions". Click "**Authorize streamlit**".
-
-
-
-
-
-12. Click "**Fork sample app**".
-
-
-
-
-
-## Deploy a sample app
-
-13. After the repository is copied to your GitHub account, the forked repository's information is prefilled into a deployment screen. Click "**Deploy!**"
-
-
-
-
-
-14. Wait for the app to build. This may take a few minutes.
-
-
-
-
-
-## You're done!
-
-Congratulations! You just deployed an app to Streamlit Community Cloud. 🎉 Your app may take a few minutes to fully build, but once it's done it will load automatically.
-
-
-
-
-
-## What's next?
-
-Start modifying the code in your forked repository and have fun exploring. Alternatively, you can [deploy another Streamlit app](/streamlit-community-cloud/deploy-your-app). Happy Streamlit-ing!🎈
diff --git a/data/streamlit-cloud/get-started/security-model.md b/data/streamlit-cloud/get-started/security-model.md
deleted file mode 100644
index 33bb5b1e7..000000000
--- a/data/streamlit-cloud/get-started/security-model.md
+++ /dev/null
@@ -1,88 +0,0 @@
----
-title: Streamlit Trust and Security
-slug: /streamlit-community-cloud/get-started/trust-and-security
----
-
-# Streamlit Trust and Security
-
-Streamlit is a framework that turns Python scripts into interactive apps, giving data scientists the ability to quickly create data and model-based apps for the entire company.
-
-A simple Streamlit app is:
-
-```python
-import streamlit as st
-number = st.slider("Pick a number: ", min_value=1, max_value=10)
-st.text("Your number is " + str(number))
-```
-
-When you `streamlit run my_app.py`, you start a web server that runs the interactive application on your local computer at `http://localhost:8501`. This is great for local development. When you want to share with your colleagues, Streamlit Community Cloud enables you to deploy and run these applications in the cloud. Streamlit Community Cloud handles all the details of containerization and provides you an interface for easily managing your deployed apps.
-
-This document is an overview of how we provide best-in-industry security for you. We'll cover all the important areas in the lifecycle of your data:
-
-- **Product Security**: how we ensure only you can create and view apps that access your data
-- **Network and Application Security**: how we ensure your data is protected when it is in our cloud
-- **Ongoing Operations**: how we stay good stewards of security best practices
-
-## Product Security
-
-### Authentication
-
-Authentication through GitHub is required to deploy or administer an app. Authentication through Google or single-use emailed links are required to view a private app for which you are not an admin. These links are valid for 15 minutes once requested. We do not store customer passwords.
-
-### Credential Storage
-
-We encrypt sensitive customer data (e.g. secrets, authentication tokens) at-rest with AES256 as described in Google's documentation.
-
-### Permissions
-
-Our permission levels inherit from the permissions you have assigned in GitHub. Users with write access to a GitHub repository for a given app will be able to make changes in the Streamlit administrative console.
-
-Only users with _admin access_ to a repository are able to **deploy and delete apps**.
-
-## Network and Application Security
-
-### Data Hosting
-
-Our physical infrastructure is hosted and managed within Google Cloud Platform (GCP) using their secure data centers. Streamlit leverages many of the platform's built-in security, privacy, and redundancy features. GCP continually monitors its data centers for risk and undergoes assessments to ensure compliance with industry standards. GCP's data centers have numerous accreditations, including ISO-27001, SOC 1 and SOC 2.
-
-### Virtual Private Cloud
-
-All of our servers are within a virtual private cloud (VPC) with firewalls and network access control lists (ACLs) to allow external access to a select few API endpoints; all other internal services are only accessible within the VPC.
-
-### Encryption
-
-All Streamlit apps are served entirely over HTTPS. All data sent to or from Streamlit over the public internet is encrypted in transit using 256-bit encryption. Our API and application endpoints are TLS only (v1.2). We use only strong cipher suites and HTTP Strict Transport Security (HSTS) to ensure browsers interact with Streamlit apps over HTTPS. We also encrypt data at rest using AES-256.
-
-### Permissions and Authentication
-
-Access to customer data is limited to authorized employees who require it for their job. We run a zero-trust corporate network so there are no corporate resources or additional privileges gained from being on Streamlit's internal network. We utilize single sign-on, 2-factor authentication (2FA), and enforce strong password policies to ensure access to all cloud-related services are protected.
-
-### Incident Response
-
-We have an internal protocol for handling security events which includes escalation procedures, rapid mitigation, and documented post-mortems. We notify customers promptly and publicize security advisories at [https://streamlit.io/advisories](https://streamlit.io/advisories).
-
-### Penetration Testing
-
-Streamlit uses third-party security tools to scan for vulnerabilities on a regular basis. Our security partners conduct periodic, intensive penetration tests on the Streamlit platform. Our product development team immediately responds to any identified issues or potential vulnerabilities to ensure the quality and security of Streamlit applications.
-
-## Security and Compliance Programs
-
-### People
-
-#### Background Checks
-
-All Streamlit employees go through a thorough background check before hiring.
-
-### Training
-
-We take a least-privilege approach to the access and handling of data. While we retain a minimal amount of customer data and limit internal access on a need-to-know basis, all employees are required to review related security policies and are trained on proper data handling to ensure they uphold our strict commitment to the privacy and security of your data.
-
-### Confidentiality
-
-All employees sign a confidentiality agreement before they start at Streamlit.
-
-## Vulnerability Control
-
-### Vulnerability Management
-
-We keep our systems up-to-date with the latest security patches and continuously monitor for new vulnerabilities through compliance and security mailing lists. This includes automatic scanning of our code repositories for vulnerable dependencies.
diff --git a/data/streamlit-cloud/index.md b/data/streamlit-cloud/index.md
deleted file mode 100644
index f67fa7fa9..000000000
--- a/data/streamlit-cloud/index.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: Streamlit Community Cloud
-slug: /streamlit-community-cloud
----
-
-# Welcome to Streamlit Community Cloud
-
-Deploy, manage, and share your Streamlit apps with the world in minutes — all for free. Your Streamlit Community Cloud account connects directly to your GitHub repository (public or private). Most apps will launch in only a few minutes. Streamlit Community Cloud handles all of the containerization so all you need to worry about is creating the app. Rapidly prototype, explore, and update apps by simply changing your code in GitHub. Most changes appear immediately!
-
-If you haven't built your first Streamlit app yet, you can check out [Get started](/library/get-started) in our Streamlit library documentation, fork an app from our App gallery, or go with [Quickstart](/streamlit-community-cloud/get-started/quickstart) which will speed-run you through creating your account and deploying an example app.
-
-
- Create your account and deploy an example app as fast as possible.
-
- Learn about Streamlit Community Cloud accounts and how to create one.
-
- A step-by-step guide on how to get your app deployed.
-
- Share or embed your app.
-
- Access logs, reboot apps, set favorites, and more.
-
- Update your email, manage connections, or delete your account.
-
-
diff --git a/data/streamlit-cloud/manage-your-account/delete-your-account.md b/data/streamlit-cloud/manage-your-account/delete-your-account.md
deleted file mode 100644
index b38f8d74c..000000000
--- a/data/streamlit-cloud/manage-your-account/delete-your-account.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: Delete your account
-slug: /streamlit-community-cloud/manage-your-account/delete-your-account
----
-
-# Delete your account
-
-Deleting your Streamlit Community Cloud account is just as easy as creating it. When you delete your account, your information, account, and all your hosted apps are deleted as well.
-
-
-
-Deleting your account is permanent and cannot be undone. Make sure you really want to delete your account and all hosted apps before proceeding. Any app you've deployed will be deleted, regardless of the workspace it was deployed from.
-
-
-
-## How to delete your account
-
-Follow these steps to delete your account:
-
-1. Sign in to Streamlit Community Cloud at share.streamlit.io and access your [Workspace settings](/streamlit-community-cloud/manage-your-account/workspace-settings).
-
-2. From the "Linked accounts" section, click "**Delete account**".
-
-
-
-
-
-3. A confirmation will display. Enter the confirmation string and click "**Delete account forever**"
-
-
-
-
-
-4. All your information and apps will be permanently deleted.
- 
-
-It's that simple! If you have any questions or run into issues deleting your account, please reach out to us on our forum. We're happy to help! 🎈
diff --git a/data/streamlit-cloud/manage-your-account/index.md b/data/streamlit-cloud/manage-your-account/index.md
deleted file mode 100644
index 101a43408..000000000
--- a/data/streamlit-cloud/manage-your-account/index.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: Manage your account
-slug: /streamlit-community-cloud/manage-your-account
----
-
-# Manage your account
-
-You can [Update your email](/streamlit-community-cloud/manage-your-account/update-your-email) or [Delete your account](/streamlit-community-cloud/manage-your-account/delete-your-account) entirely through [Workspace settings](/streamlit-community-cloud/manage-your-account/workspace-settings).
-
-When using Streamlit Community Cloud, you have two identities behind your account: a primary identity (Google or email) and source control (GitHub). Your primary identity allows other users to share private apps with you and grant you access to their analytics. Your source control identity allows you to deploy apps from GitHub repositories and manage them through your Streamlit Community Cloud workspace.
-
-## Access your workspace settings
-
-To manage your account, sign in to share.streamlit.io and click "**Settings**" in the top right corner to access your workspace settings.
-
-
-
-
-
-Learn more about how to [Update your email](/streamlit-community-cloud/manage-your-account/update-your-email) and [Delete your account](/streamlit-community-cloud/manage-your-account/delete-your-account).
diff --git a/data/streamlit-cloud/manage-your-account/manage-your-github-connection.md b/data/streamlit-cloud/manage-your-account/manage-your-github-connection.md
deleted file mode 100644
index 65aa4735c..000000000
--- a/data/streamlit-cloud/manage-your-account/manage-your-github-connection.md
+++ /dev/null
@@ -1,96 +0,0 @@
----
-title: Manage your GitHub connection
-slug: /streamlit-community-cloud/manage-your-account/manage-your-github-connection
----
-
-# Manage your GitHub connection
-
-If you did not connect GitHub when you created your account or need to correct your GitHub authorization, this page is for you! If you just need to add an organization to your account, skip ahead to [Authorizing with an organization](#authorizing-with-an-organization).
-
-If you are not fully logged in and authorized to both a primary identity (Google or email) and source control (GitHub), there will be a warning symbol in the upper-right corner of your workspace. This can mean one of three things:
-
-* You are not signed in to a primary identity (Google or email).
- * See [Connect Google to your account](/streamlit-community-cloud/manage-your-account/update-your-email#connect-google-to-your-account).
-* You are not signed in to source control (GitHub.)
- * See [Connecting GitHub to an existing primary identity](#connecting-github-to-an-existing-primary-identity).
-* Your source control has incomplete permissions.
- * Access your workspace settings see [Authorize Streamlit to access private repositories](#authorize-streamlit-to-access-private-repositories).
-
-
-
-## Connecting GitHub to an existing primary identity
-
-If you created your account without connecting GitHub or if you disconnected GitHub from your account, you can reconnect.
-
-1. Click "**Settings**" in the upper-right corner of your workspace.
-2. If you do not have GitHub connected, a warning is displayed saying, "**You are not signed in with a source control account**".
-
- If instead you see "**Streamlit does not have access to private repos on this GitHub account**" skip to step 5.
-3. Click "**Sign in with GitHub**".
-
-
-
-
-
-4. Click "**Authorize streamlit**".
-
-
-
-
-
-### Authorize Streamlit to access private repositories
-
-5. After completing the first authorization, your workspace settings will still have a warning, "**Streamlit does not have access to private repos on this GitHub account**".
-
-6. Click "**Allow access**".
-
-
-
-
-
-7. Click "**Authorize streamlit**".
-
-
-
-
-
-GitHub is now connected to your account! 🥳
-
-## Authorizing with an organization
-
-If you are in an organization, you can grant or request access to that organization when you connect your GitHub account. Read more about [Organization access](/streamlit-community-cloud/get-started/connect-your-github-account#organization-access).
-
-If your GitHub account is already connected, you can remove permissions in your GitHub settings and force Streamlit to reprompt for GitHub authorization the next time you sign into Streamlit Community Cloud.
-
-### Revoke and reauthorize
-
-1. From your workspace, click on your workspace name in the upper-right corner. Click "**Sign out**" to sign out of Streamlit Community Cloud.
-
-
-
-
-
-2. Go to your GitHub application settings at github.com/settings/applications.
-3. Click on the three dots to open the overflow menu for "**Streamlit**" and click "**Revoke**".
-
-
-
-5. Return to share.streamlit.io and sign in. You will be prompted to authorize GitHub as explained in [Connect GitHub](/streamlit-community-cloud/get-started/connect-your-github-account#organization-access).
-
-### Granting previously denied access
-
-If an organization owner has restricted Streamlit's access or restricted all OAuth applications, they may need to directly modify their permissions in GitHub. If an organization has restricted Streamlit's access, a red "**X**" will appear next to the organization when you are prompted to authorize with your GitHub account.
-
-
-
-
-
-See GitHub's documentation on OAuth apps and organizations.
diff --git a/data/streamlit-cloud/manage-your-account/sign-in-sign-out.md b/data/streamlit-cloud/manage-your-account/sign-in-sign-out.md
deleted file mode 100644
index 1e0804e2f..000000000
--- a/data/streamlit-cloud/manage-your-account/sign-in-sign-out.md
+++ /dev/null
@@ -1,72 +0,0 @@
----
-title: Sign in & sign out
-slug: /streamlit-community-cloud/manage-your-account/sign-in-sign-out
----
-
-# Sign in & sign out
-
-Once you've created your account, you can sign in to share.streamlit.io and follow the steps below.
-
-
-
-## Sign in with Google
-
-1. Visit share.streamlit.io and click "**Continue with Google**".
-
-
-
-
-
-2. Enter your Google account credentials.
-
-
-
-
-
-3. If your account is already linked to GitHub, you may be immediately prompted to sign in with GitHub. Once you have signed in, you can [Explore your workspace!](/streamlit-community-cloud/get-started/explore-your-workspace). 🎈
-
-## Sign in with GitHub
-
-1. Visit share.streamlit.io and click "**Continue with GitHub**".
-
-
-
-
-
-2. Enter your GitHub credentials.
-
-
-
-
-
-3. Once you have signed in to GitHub, you can [Explore your workspace!](/streamlit-community-cloud/get-started/explore-your-workspace). 🎈
-
-## Sign in with Email
-
-1. Visit share.streamlit.io and enter the email you used to create your Streamlit Community Cloud account. Click "**Continue with email**".
-
-
-
-
-
-2. You will see a confirmation message asking you to check your email.
-
-
-
-
-
-3. Check your inbox for an email with the subject "**Sign in to Streamlit Cloud**". Click the link in the email to sign in to Streamlit Community Cloud. Note that this link will expire in 15 minutes and can only be used once.
-
-
-
-
-
-3. Once you click the link in your email, you can [Explore your workspace!](/streamlit-community-cloud/get-started/explore-your-workspace). 🎈
-
-## Sign out of your account
-
-From your workspace, click on your workspace name in the upper-right corner. Click "**Sign out**".
-
-
-
-
\ No newline at end of file
diff --git a/data/streamlit-cloud/manage-your-account/update-your-email.md b/data/streamlit-cloud/manage-your-account/update-your-email.md
deleted file mode 100644
index 8238c68ac..000000000
--- a/data/streamlit-cloud/manage-your-account/update-your-email.md
+++ /dev/null
@@ -1,76 +0,0 @@
----
-title: Update your email
-slug: /streamlit-community-cloud/manage-your-account/update-your-email
----
-
-# Update your email
-
-If you wish to update your email on Streamlit Community Cloud, you can do so via your [Workspace settings](/streamlit-community-cloud/manage-your-account/workspace-settings). Updating your email changes the primary identity of your account. Once updated, if your account's email is associated with a Google account, you can sign in with Google OAuth. Otherwise, you through emailed links. The latter involves typing in your email, after which we'll send you a unique, single-use link (valid for 15 minutes).
-
-If you are signed in to GitHub and don't already have a primary identity on your account, see [Connect Google to your account](#connect-google-to-your-account).
-
-## How to update your email
-
-1. Sign in to Streamlit Community Cloud at share.streamlit.io.
-2. Click "**Settings**" in the page's top-right corner.
- 
-
-3. Click "**Update email**" within the "**Linked accounts**" section.
- 
-
-4. Enter your new email and click "**Update email**."
- 
-
-5. You'll see a confirmation dialog asking you to check your email for a confirmation link. Click "**Done**."
- 
-
-6. Your account settings will show "**Update pending**" until you complete the next step.
- 
-
-7. Check your inbox for an email from Streamlit containing a "**Change email**" button and a confirmation link. This one-time link expires in 15 minutes. Click either one to confirm your new email address for Streamlit Community Cloud. Before doing so, ensure you access the link from the same browser session where you are logged in to Streamlit Community Cloud.
-
-
-
- If you access the confirmation link from a browser session where you are not logged in to Streamlit Community Cloud, the confirmation link will not complete the process. You will be prompted to sign in. If you try to sign in with your new email, you will create a second account instead. See [Troubleshooting](#troubleshooting).
-
-
-
- 
-
-8. A confirmation will display to confirm your email update is complete! 🎈
- 
-
-## Resend your confirmation link
-
-If your confirmation link expires, don't worry! You can resend it by following these steps:
-
-1. Sign in to Streamlit Community Cloud at share.streamlit.io and click "**Settings**" in the page's top-right corner.
-2. Click "**Update pending**"
- 
-
-3. Click "**Resend email**"
- 
-
-4. Continue from step 4 of [How to update your email](#how-to-update-your-email).
-
-## Troubleshooting
-
-If you click the confirmation link in a browser session where you are not signed in, you will be informed that "Sign in is required." If you try to sign in with your new email, you will create a second account instead. You cannot resend your confirmation link while you have this second account. If you accidentally created a second account, you can follow the steps to [Delete your account](/streamlit-community-cloud/manage-your-account/delete-your-account) to get rid of the duplicate. Afterwards, [Resend your confirmation link](#resend-your-confirmation-link) from your first account.
-
-## Connect Google to your account
-
-1. If you signed up with GitHub and did not create a primary identity, your workspace will show a warning icon in the upper right corner. Click "**Settings**" to access your workspace settings.
-
- 
-
-2. When you access your workspace settings, a warning is displayed: "You are not signed in with a primary identity account." Click "**Sign in with Google**" and follow Google's authentication prompts.
-
-
-
-
-
-3. Your account now has both a primary identity and source control account.
-
-
-
-
diff --git a/data/streamlit-cloud/manage-your-account/workspace-settings.md b/data/streamlit-cloud/manage-your-account/workspace-settings.md
deleted file mode 100644
index b560e3269..000000000
--- a/data/streamlit-cloud/manage-your-account/workspace-settings.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: Workspace settings
-slug: /streamlit-community-cloud/manage-your-account/workspace-settings
----
-
-# Workspace settings
-
-From your workspace settings you can [Manage your account](/streamlit-community-cloud/manage-your-account), see your [App resources and limits](/streamlit-community-cloud/manage-your-app#app-resources-and-limits) and access support resources.
-
-## Access your workspace settings
-
-From your workspace at share.streamlit.io, click "**Settings**" in the upper-right corner.
-
-
-
-## Linked accounts
-
-The "**Linked accounts**" section shows your current primary identity and source control account. To learn more, see [Manage your account](/streamlit-community-cloud/manage-your-account).
-
-
-
-## Limits
-
-The "**Limits**" section shows your current resources and limits. To learn more, see [App resources and limits](/streamlit-community-cloud/manage-your-app#app-resources-and-limits).
-
-
-
-## Support
-
-The "**Support**" section provides a convenient list of useful resources so you know where to go for help.
-
-
diff --git a/data/streamlit-cloud/manage-your-app/app-analytics.md b/data/streamlit-cloud/manage-your-app/app-analytics.md
deleted file mode 100644
index 8e486cef8..000000000
--- a/data/streamlit-cloud/manage-your-app/app-analytics.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: App analytics
-slug: /streamlit-community-cloud/manage-your-app/app-analytics
----
-
-# App analytics
-
-Streamlit Community Cloud allows you to see the viewership of each of your apps. Specifically, you can see:
-* The total viewers count of your app (counted from April 2022).
-* The most recent unique viewers (capped up to your last 20 viewers).
-* A relative timestamp of each unique viewer's last visit.
-
-
-
-## Access your app analytics
-
-You can get to your app's analytics:
-* [From your workspace](#access-app-analytics-from-your-workspace).
-* [From your Cloud logs](#access-app-analytics-from-your-cloud-logs).
-
-### Access app analytics from your workspace
-
-From your workspace at share.streamlit.io, click the overflow icon (more_vert) next to your app. Click "**Analytics**".
-
-
-
-Alternatively, from the top of your workspace, click "**Analytics**".
-
-
-
-### Access app analytics from your Cloud logs
-
-From your app at `.streamlit.app`, click "**Manage app**" in the lower-right corner.
-
-
-
-Click the overflow menu icon (more_vert) and click "**Analytics**".
-
-
-
-## Switch between apps
-
-Once you are in the analytics modal, you can switch between apps in your workspace from the drop-down list. Remember to switch workspaces if you want to view analytics for an app in another workspace.
-
-
-
-## App viewers
-
-For public apps, we anonymize all viewers outside your workspace to protect their privacy and display anonymous viewers as random pseudonyms. You'll still be able to see the identities of fellow members in your workspace, including any viewers you've invited (once they've accepted).
-
-
-
-When you invite a viewer to an app, they gain access to analytics as well. Additionally, if someone is invited as a viewer to *any* app in your workspace, they can see analytics for all public apps in your workspace and invite additional viewers themselves. A viewer in your workspace may see the emails of developers and other viewers in your workspace through analytics.
-
-
-
-Meanwhile, for private apps where you control who has access, you will be able to see the specific users who recently viewed your apps.
-
-Additionally, you may occasionally see anonymous users in a private app. Rest assured, these anonymous users _do_ have authorized view access granted by you or your workspace members.
-
-Common reasons why users show up anonymously are:
-
-1. The app was previously public.
-2. The given viewer viewed the app in April 2022, when the Streamlit team was honing user identification for this feature.
-3. The given viewer previously disconnected their primary identity (Google or email) and source control identity (GitHub).
-
-See Streamlit's general Privacy Notice.
diff --git a/data/streamlit-cloud/manage-your-app/app-settings.md b/data/streamlit-cloud/manage-your-app/app-settings.md
deleted file mode 100644
index 678bd5a6e..000000000
--- a/data/streamlit-cloud/manage-your-app/app-settings.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: App settings
-slug: /streamlit-community-cloud/manage-your-app/app-settings
----
-
-# App settings
-
-This page is about your app settings on Streamlit Community Cloud. From your app settings you can [view or modify your app's URL](/streamlit-community-cloud/deploy-your-app#custom-subdomains), [manage public or private access to your apps](/streamlit-community-cloud/share-your-app) and [update your saved secrets for your apps](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-If you access "**Settings**" from your [App menu](/library/advanced-features/app-menu) in the upper-right corner of your running app, you can access features to control the appearance of your app while its running.
-
-## Access your app settings
-
-You can get to your app's settings:
-* [From your workspace](#access-app-settings-from-your-workspace).
-* [From your Cloud logs](#access-app-settings-from-your-cloud-logs).
-
-### Access app settings from your workspace
-
-From your workspace at share.streamlit.io, click the overflow icon (more_vert) next to your app. Click "**Settings**".
-
-
-
-### Access app settings from your Cloud logs
-
-From your app at `.streamlit.app`, click "**Manage app**" in the lower-right corner.
-
-
-
-Click the overflow menu icon (more_vert) and click "**Settings**".
-
-
-
-## Change your app settings
-
-### View or change your app's URL
-Read more about [Custom subdomains](/streamlit-community-cloud/deploy-your-app#custom-subdomains).
-
-
-
-### Update your app's share settings
-Learn how to [Share your app](/streamlit-community-cloud/share-your-app).
-
-
-
-### Update your secrets
-Learn more about [Secrets management](/streamlit-community-cloud/deploy-your-app/secrets-management).
-
-
diff --git a/data/streamlit-cloud/manage-your-app/delete-your-app.md b/data/streamlit-cloud/manage-your-app/delete-your-app.md
deleted file mode 100644
index 5ac7a2ad9..000000000
--- a/data/streamlit-cloud/manage-your-app/delete-your-app.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: Delete your app
-slug: /streamlit-community-cloud/manage-your-app/delete-your-app
----
-
-# Delete your app
-
-If you need to delete your app, it's simple and easy. There are several cases where you may need to delete your app:
-
-* You have finished playing around with an example app.
-* You want to deploy from a private repository but already have a private app.
-* You want to change the Python version for your app or otherwise redeploy your app.
-
-If you delete your app and intend to immediately redploy it, your custom subdomain should be immediately available for reuse.
-
-You can delete your app:
-* [From your workspace](#delete-your-app-from-your-workspace).
-* [From your Cloud logs](#delete-your-app-from-your-cloud-logs).
-
-### Delete your app from your workspace
-
-1. From your workspace at share.streamlit.io, click the overflow icon (more_vert) next to your app. Click "**Delete**".
-
- 
-
-2. A confirmation will display. Enter the required confirmation string and click "**Delete**".
-
-
-
-
-
-### Delete your app from your Cloud logs
-
-1. From your app at `.streamlit.app`, click "**Manage app**" in the lower-right corner.
-
- 
-
-2. Click the overflow menu icon (more_vert) and click "**Delete app**".
-
- 
-
-3. A confirmation will display. Enter the required confirmation string and click "**Delete**".
-
-
-
-
diff --git a/data/streamlit-cloud/manage-your-app/favorite-your-app.md b/data/streamlit-cloud/manage-your-app/favorite-your-app.md
deleted file mode 100644
index 57a24acf8..000000000
--- a/data/streamlit-cloud/manage-your-app/favorite-your-app.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: Favorite your app
-slug: /streamlit-community-cloud/manage-your-app/favorite-your-app
----
-
-# Favorite your app
-
-Streamlit Community Cloud supports a "favorite" feature that lets you quickly access your apps from your workspace. Favorited apps appear at the top of their workspace with a yellow star (star) beside them. You can favorite and unfavorite apps in any workspace to which you have access as a developer or invited viewer.
-
-
-
-
-
-Favorites are specific to your account. Other members of your workspace cannot see which apps you have favorited.
-
-
-
-## Favoriting and unfavoriting your app
-
-You can favorite your app:
-* [From your workspace](#favorite-your-app-from-your-workspace).
-* [From your app](#favorite-your-app-from-your-app-toolbar)!
-
-### Favorite your app from your workspace
-
-1. From your workspace at share.streamlit.io, click the overflow icon (more_vert) next to your app. Click "**Favorite**".
-
- 
-
-2. Your favorited app will move to the top of your list (with other favorited apps if you have them) and display with a yellow star.
-
- 
-
-* Once favorited, from the same menu, click "**Unfavorite**" to remove the star.
-
- 
-
-Alternatively, you can favorite and unfavorite apps by clicking directly on the star next to their names. (Hover over an unfavorited app to reveal an empty star icon next to its name.)
-
-### Favorite your app from your app toolbar
-
-From your app at `.streamlit.app`, click the star (star_border/star) in the upper-right corner to toggle your app's favorite status.
-
-
diff --git a/data/streamlit-cloud/manage-your-app/index.md b/data/streamlit-cloud/manage-your-app/index.md
deleted file mode 100644
index aafed0718..000000000
--- a/data/streamlit-cloud/manage-your-app/index.md
+++ /dev/null
@@ -1,136 +0,0 @@
----
-title: Manage your app
-slug: /streamlit-community-cloud/manage-your-app
----
-
-# Manage your app
-
-You can manage your deployed app from your workspace at share.streamlit.io or directly from `.streamlit.app`. You can view, deploy, delete, reboot, or favorite an app.
-
-## Manage your app from your workspace
-
-Streamlit Community Cloud is organized into workspaces, which automatically group your apps according to the corresponding GitHub repository's owner. Your workspace is indicated in the upper-right corner. You will have one workspace that matches your GitHub username and additional workspaces for any GitHub organization or user who has granted you access.
-
-Additionally, if you have view-only access to an app, you will be able to see that app's workspace. When you do not have developer access to an app, your management options for that app will be restricted as shown in the following sections.
-
-To deploy or manage any app, always switch to the workspace matching the repository's owner first.
-
-
-
-At the top of your workspace, "**Analytics**" is a shortcut to [App analytics](/streamlit-community-cloud/manage-your-app/app-analytics) and "**Settings**" links to your [Workspace settings](/streamlit-community-cloud/manage-your-account/workspace-settings) (not to be confused with [App settings](/streamlit-community-cloud/manage-your-app/app-settings) for each of your apps).
-
-### App overflow menus
-
-Each app has a menu accessible from the overflow icon (more_vert) to the right.
-
-* **Copy URL** — See [Copy your app's URL](/streamlit-community-cloud/share-your-app#copy-your-apps-url)
-* **Favorite** — See [Favorite your app](/streamlit-community-cloud/manage-your-app/favorite-your-app)
-* **Analytics** — See [App analytics](/streamlit-community-cloud/manage-your-app/app-analytics)
-* **Reboot** — See [Reboot your app](/streamlit-community-cloud/manage-your-app/reboot-your-app)
-* **Delete** — See [Delete your app](/streamlit-community-cloud/manage-your-app/delete-your-app)
-* **Settings** — See [App settings](/streamlit-community-cloud/manage-your-app/app-settings)
-
-
-
-If you have view-only access to an app, options will be restricted in that app's menu.
-
-
-
-## Manage your app directly from your app
-
-You can manage your deployed app directly from the app itself! Just make sure you are signed in to Streamlit Community Cloud then visit your app.
-
-### Streamlit Community Cloud logs
-
-1. From your app at `.streamlit.app`, click "**Manage app**" in the lower-right corner.
-
- 
-
-2. Once you've clicked on "**Manage app**", you will be able to view your app's logs. This is your primary place to troubleshoot any issues with your app.
-
- 
-
-3. You can access more developer options by clicking the overflow icon (more_vert) at the bottom of your Cloud logs. To conveniently download your logs, click "**Download log**".
-
- 
-
-
-
-
-
-Other options accessible from Cloud logs are:
-
-* **Analytics** — See [App analytics](/streamlit-community-cloud/manage-your-app/app-analytics).
-* **Reboot app** — See [Reboot your app](/streamlit-community-cloud/manage-your-app/reboot-your-app).
-* **Delete app** — See [Delete your app](/streamlit-community-cloud/manage-your-app/delete-your-app).
-* **Settings** — See [App settings](/streamlit-community-cloud/manage-your-app/app-settings).
-* **Your apps** — Takes you to your [app workspace](#manage-your-app-from-your-workspace).
-* **Documentation** — Takes you to our documentation.
-* **Support** — Takes you to our forums!
-
-
-
-
-
-
-
-
-
-### App menus
-
-From your app at `.streamlit.app`, you can always access your [app's menu](/library/advanced-features/app-menu) just like you can when developing locally. The option to deploy your app is removed, but you can still clear your cache from here.
-
-
-
-## Manage your app in GitHub
-
-### Update your app
-
-Your GitHub repository is the source for the app, so that means that any time you push an update to your repo you'll see it reflected in the app in almost real time. Try it out!
-
-Streamlit also smartly detects whether you touched your dependencies, in which case it will automatically do a full redeploy for you—which will take a little more time. But since most updates don't involve dependency changes, you should usually see your app update in real time.
-
-### Add or remove dependencies
-
-You can add/remove dependencies at any point by updating `requirements.txt` (Python dependenciess) or `packages.txt` (Linux dependencies) and committing the changes to your repository on GitHub. This will cause Streamlit Community Cloud to detect there was a change in your dependencies and automatically trigger (re)installation.
-
-It is best practice to pin your Streamlit version in `requirements.txt`. Otherwise, the version may be auto-upgraded at any point without your knowledge, which could lead to undesired results (e.g. when we deprecate a feature in Streamlit).
-
-## App resources and limits
-
-### Resource limits
-
-All Streamlit Community Cloud users have access to the same resources and are subject to the same limits (1 GB of RAM).
-If your app is running slowly or you're hitting the '😦 Oh no.' page, we first highly recommend going through and implementing the suggestions in the following blog posts to prevent your app from hitting the resource limits and to detect if your Streamlit app leaks memory:
-
-- Common app problems: Resource limits
-- 3 steps to fix app memory leaks
-
-If your app exceeds its resourse limits, developers and viewers alike will see '😦 Oh no.'
-
-
-
-
-
-If see '😦 Oh no.' when viewing your app, first check your Cloud logs for any specific errors. If there are no errors in your Cloud logs you are likely dealing with a resource issue.
-
-#### Developer view
-
-If you are logged into a developer account for an app over its limits, you can access "**Manage app**" from the lower-right corner of the app to reboot it and clear its memory. "**Manage app**" will be red and have a warning icon (error).
-
-
-
-### App hibernation
-
-All apps without traffic for 7 consecutive days will automatically go to sleep. This is done to alleviate resources and allow the best communal use of the platform! If you would like to keep your app awake, simply visit the app to create traffic or commit your app's repository, even if it's an empty commit!
-
-If left alone your app will go to sleep at the 7 day mark. When someone visits the app after this, they will see the sleeping page:
-
-
-
-
-To wake the app up, click "**Yes, get this app back up!**" This can be done by *anyone* who has access to view the app, not just the app developer!
-
-You can see which of your apps are asleep from your workspace. Sleeping apps have a moon icon (bedtime) to the right.
-
-
diff --git a/data/streamlit-cloud/manage-your-app/reboot-your-app.md b/data/streamlit-cloud/manage-your-app/reboot-your-app.md
deleted file mode 100644
index ae897ac36..000000000
--- a/data/streamlit-cloud/manage-your-app/reboot-your-app.md
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: Reboot your app
-slug: /streamlit-community-cloud/manage-your-app/reboot-your-app
----
-
-# Reboot your app
-
-If you need to clear your app's memory or force a fresh build after modifying a file that Streamlit Community Cloud doesn't monitor, you may need to reboot your app. This will interrupt any user who may currently be using your app and may take a few minutes for your app to re-deploy. Anyone visiting your app will see "Your app is in the oven" during a reboot.
-
-Rebooting your app on Streamlit Community Cloud is easy! You can reboot your app:
-* [From your workspace](#reboot-your-app-from-your-workspace).
-* [From your Cloud logs](#reboot-your-app-from-your-cloud-logs).
-
-### Reboot your app from your workspace
-
-1. From your workspace at share.streamlit.io, click the overflow icon (more_vert) next to your app. Click "**Reboot**".
-
- 
-
-2. A confirmation will display. Click "**Reboot**".
-
-
-
-
-
-### Reboot your app from your Cloud logs
-
-1. From your app at `.streamlit.app`, click "**Manage app**" in the lower-right corner.
-
- 
-
-2. Click the overflow menu icon (more_vert) and click "**Reboot app**".
-
- 
-
-3. A confirmation will display. Click "**Reboot**".
-
-
-
-
diff --git a/data/streamlit-cloud/share-your-app/embed-your-app.md b/data/streamlit-cloud/share-your-app/embed-your-app.md
deleted file mode 100644
index 234af99f2..000000000
--- a/data/streamlit-cloud/share-your-app/embed-your-app.md
+++ /dev/null
@@ -1,152 +0,0 @@
----
-title: Embed your app
-slug: /streamlit-community-cloud/share-your-app/embed-your-app
----
-
-# Embed your app
-
-Embedding Streamlit Community Cloud apps enriches your content by integrating interactive, data-driven applications directly within your pages. Whether you're writing a blog post, a technical document, or sharing resources on platforms like Medium, Notion, or even StackOverflow, embedding Streamlit apps adds a dynamic component to your content. This allows your audience to interact with your ideas, rather than merely reading about them or looking at screenshots.
-
-Streamlit Community Cloud supports both [iframe](#embedding-with-iframes) and [oEmbed](#embedding-with-oembed) methods for embedding **public** apps. This flexibility enables you to share your apps across a wide array of platforms, broadening your app's visibility and impact. In this guide, we'll cover how to use both methods effectively to share your Streamlit apps with the world.
-
-## Embedding with iframes
-
-Streamlit Community Cloud supports embedding **public** apps using the subdomain scheme. To embed a public app, add the query parameter `/?embed=true` to the end of the `*.streamlit.app` URL.
-
-For example, say you want to embed the 30DaysOfStreamlit app. The URL to include in your iframe is: `https://30days.streamlit.app/?embed=true`:
-
-```javascript
-
-```
-
-
-
-
-
-There will be no official support for embedding private apps.
-
-
-
-In addition to allowing you to embed apps via iframes, the `?embed=true` query parameter also does the following:
-
-- Removes the toolbar with the app menu icon (more_vert).
-- Removes the padding at the top and bottom of the app.
-- Removes the footer.
-- Removes the colored line from the top of the app.
-
-For granular control over the embedding behavior, Streamlit allows you to specify one or more instances of the `?embed_options` query parameter (e.g. to show the toolbar, open the app in dark theme, etc). [Click here for a full list of Embed options.](#embed-options)
-
-## Embedding with oEmbed
-
-Streamlit's oEmbed support allows for a simpler embedding experience. You can directly drop a Streamlit app's URL into a Medium, Ghost, or Notion page (or any of more than 700 content providers that supports oEmbed or embed.ly). The embedded app will automatically appear! This helps Streamlit Community Cloud apps seamlessly integrate into these platforms, improving the visibility and accessibility of your apps.
-
-### Example
-
-When creating content in a Notion page, Medium article, or Ghost blog, you only need to paste the app's URL and hit "**Enter**". The app will then render automatically at that spot in your content. You can use your undecorated app URL without the `?embed=true` query parameter.
-
-```
-https://30days.streamlit.app/
-```
-
-Here's an example of @chrieke's Prettymapp app embedded in a Medium article:
-
-
-
-
-
-Ensure the platform hosting the embedded Streamlit app supports oEmbed or embed.ly.
-
-
-
-### Key Sites for oEmbed
-
-oEmbed should work out of the box for several platforms including but not limited to:
-
-- Medium
-- Notion
-- Looker
-- Tableau
-- Ghost
-- Discourse
-- StackOverflow
-- W3
-- Reddit
-
-Please check the specific platform's documentation to verify support for oEmbed.
-
-### iframe versus oEmbed
-
-The only noteworthy differences between the methods is that iframing allows you to customize the app's embedding behavior (e.g. showing the toolbar, opening the app in dark theme, etc) using the various `?embed_options` described in the next section.
-
-## Embed options
-
-When [Embedding with iframes](#embedding-with-iframes), Streamlit allows you to specify one or more instances of the `?embed_options` query parameter for granular control over the embedding behavior.
-
-Both `?embed` and `?embed_options` are invisible to [`st.experimental_get_query_params`](/library/api-reference/utilities/st.experimental_get_query_params) and [`st.experimental_set_query_params`](/library/api-reference/utilities/st.experimental_set_query_params). The former ignores the embed query parameters and does not return them, while the latter disallows setting embed query parameters.
-
-The supported values for `?embed_options` are listed below:
-
-1. Show the toolbar at the top right of the app which includes the app menu (more_vert), running man, and link to GitHub.
-
- ```javascript
- /?embed=true&embed_options=show_toolbar
- ```
-
-2. Show padding at the top and bottom of the app.
-
- ```javascript
- /?embed=true&embed_options=show_padding
- ```
-
-3. Show the footer reading "Made with Streamlit."
-
- ```javascript
- /?embed=true&embed_options=show_footer
- ```
-
-4. Show the colored line at the top of the app.
-
- ```javascript
- /?embed=true&embed_options=show_colored_line
- ```
-
-5. Disable scrolling for the main body of the app. (The sidebar will still be scrollable.)
-
- ```javascript
- /?embed=true&embed_options=disable_scrolling
- ```
-
-6. Open the app with light theme.
-
- ```javascript
- /?embed=true&embed_options=light_theme
- ```
-
-7. Open the app with dark theme.
-
- ```javascript
- /?embed=true&embed_options=dark_theme
- ```
-
-You can also combine the params:
-
-```javascript
-/?embed=true&embed_options=show_toolbar&embed_options=show_padding&embed_options=show_footer&embed_options=show_colored_line&embed_options=disable_scrolling
-```
-
-### Build an embed link
-
-You can conveniently build an embed link for your app — right from your app!
-
-1. From your app at `.streamlit.app`, click "**Share**" in the upper-right corner.
-2. Click "**Embed**" to access a list of selectable embed options.
-
- 
-
-3. Select your embed options and click "**Get embed link**" to copy the embed link to your clipboard.
-
- 
diff --git a/data/streamlit-cloud/share-your-app/index.md b/data/streamlit-cloud/share-your-app/index.md
deleted file mode 100644
index 0db61028b..000000000
--- a/data/streamlit-cloud/share-your-app/index.md
+++ /dev/null
@@ -1,151 +0,0 @@
----
-title: Share your app
-slug: /streamlit-community-cloud/share-your-app
----
-
-# Share your app
-
-Now that your app is deployed you can easily share it and collaborate on it. But first, let's take a moment and do a little joy dance for getting that app deployed! 🕺💃
-
-Your app is now live at a fixed URL, so go wild and share it with whomever you want. Your app will inherit permissions from your GitHub repo, meaning that if your repo is private your app will be private and if your repo is public your app will be public. If you want to change that you can simply do so from the app settings menu.
-
-You are only allowed one private app at a time. If you've deployed from a private repository, you will have to make that app public or delete it before you can deploy another app from a private repository. Only developers can change your app between public and private.
-
-- [Make your app public or private](#make-your-app-public-or-private)
-- [Share your public app](#share-your-public-app)
-- [Share your private app](#share-your-private-app)
-
-## Make your app public or private
-
-If you deployed your app from a public repository, your app will be public by default. If you deployed your app from a private repository, you will need to make the app public if you want to freely share it with the community at large.
-
-### Set privacy from your app settings
-
-1. Access your [App settings](/streamlit-community-cloud/manage-your-app/app-settings) and go to the "**Sharing**" section.
-
- 
-
-2. Set your app's privacy under "Who can view this app." Select "**This app is public and searchable**" to make your app public. Select "**Only specific people can view this app**" to make your app private.
-
- 
-
-### Set privacy from the share button
-
-1. From your app at `.streamlit.app`, click "**Share**" in the upper-right corner.
-
- 
-
-2. Toggle your app between public and private by clicking "**Make this app public**".
-
- 
-
-## Share your public app
-
-Once your app is public, just give anyone your app's URL and they view it! Streamlit Community Cloud has several convenient shortcuts for sharing your app.
-
-### Share your app on social media
-
-1. From your app at `.streamlit.app`, click "**Share**" in the upper-right corner.
-2. Click "**Social**" to access convenient social media share buttons.
-
- 
-
-
-
-Use the social media sharing buttons to post your app on our forum! We'd love to see what you make and perhaps feature your app as our app of the month. 💖
-
-
-
-### Invite viewers by email
-
-Whether your app is public or private, you can send an email invite to your app directly from Streamlit Community Cloud. This grants the viewer access to analytics for all your public apps and the ability to invite other viewers to your workspace. Developers and invited viewers are identified by their email in analytics instead of appearing anonymously (if they view any of your apps while logged in). Read more about viewers in [App analytics](/streamlit-community-cloud/manage-your-app/app-analytics).
-
-1. From your app at `.streamlit.app`, click "**Share**" in the upper-right corner.
-2. Enter an email address and click "**Invite**".
-
- 
-
-3. Invited users will get a direct link to your app in their inbox.
-
- 
-
-### Copy your app's URL
-
-You can convenitiently copy your app's URL from the share menu or from your workspace.
-
-* From your app click "**Share**" in the upper-right corner then click "**Copy link**".
-
- 
-
-* From your workspace click the overflow menu icon (more_vert) then click "**Copy URL**".
-
- 
-
-### Add a badge to your GitHub repository
-
-To help others find and play with your Streamlit app, you can add Streamlit's GitHub badge to your repo. Below is an enlarged example of what the badge looks like. Clicking on the badge takes you to—in this case—Streamlit's Face-GAN Demo.
-
-
-
-
-Once you deploy your app, you can embed this badge right into your GitHub README.md by adding the following Markdown:
-
-```markdown
-[](https://.streamlit.app)
-```
-
-
-
-Be sure to replace `https://.streamlit.app` with the URL of your deployed app!
-
-
-
-## Share your private app
-
-By default an app deployed from a private repository will be private to the developers in the workspace. A private app will not be visible to anyone else unless you grant them explicit permission. You can grant permission by adding them as a developer on GitHub or by adding them as a viewer on Streamlit Community Cloud.
-
-Once you have added someone's email address to your app's viewer list, that person will be able to sign in and view your private app. If their email is associated to a Google account, they will be able to sign in with Google OAuth. Otherwise, they will be able to sign in with single-use, emailed links. Streamlit sends an email invitation with a link to your app every time you invite someone.
-
-
-
-When you add a viewer to any app in your workspace, they are granted access to analytics for that app as well as analytics for all your public apps. They can also pass these permissions to others by inviting more viewers. All viewers and developers in your workspace are identified by their email in analytics. Furthermore, their emails show in analytics for every app in your workspace and not just apps they are explicitly invited to. Read more about viewers in [App analytics](/streamlit-community-cloud/manage-your-app/app-analytics)
-
-
-
-### Invite viewers from the share button
-
-1. From your app at `.streamlit.app`, click "**Share**" in the upper-right corner.
-
- 
-
-2. Enter the email to send an invitation to and click "**Invite**".
-
- 
-
-3. Invited users appear in the list below.
-
- 
-
-4. Invited users will get a direct link to your app in their inbox.
-
- 
-
-* To remove a viewer, simply access the share menu as above and click the close next to their name.
-
- 
-
-### Invite viewers from your app settings
-
-1. Access your [App settings](/streamlit-community-cloud/manage-your-app/app-settings) and go to the "**Sharing**" section.
-
- 
-
-2. Add or remove users from the list of viewers. Click "**Save**".
-
- 
diff --git a/data/streamlit-cloud/share-your-app/indexability.md b/data/streamlit-cloud/share-your-app/indexability.md
deleted file mode 100644
index dd47d163c..000000000
--- a/data/streamlit-cloud/share-your-app/indexability.md
+++ /dev/null
@@ -1,65 +0,0 @@
----
-title: SEO and search indexability
-slug: /streamlit-community-cloud/share-your-app/indexability
----
-
-# SEO and search indexability
-
-When you deploy a public app to Streamlit Community Cloud, it is automatically indexed by search engines like Google and Bing on a weekly basis. 🎈 This means that anyone can find your app by searching for its custom subdomain (e.g. "traingenerator.streamlit.app") or by searching for the app's title.
-
-## Get the most out of app indexability
-
-Here are some tips to help you get the most out of app indexability:
-
-1. [Make sure your app is public](#make-sure-your-app-is-public)
-2. [Choose a custom subdomain early](#choose-a-custom-subdomain-early)
-3. [Choose a descriptive app title](#choose-a-descriptive-app-title)
-4. [Customize your app's meta description](#customize-your-apps-meta-description)
-
-### Make sure your app is public
-
-All public apps hosted on Streamlit Community Cloud are indexed by search engines. If your app is private, it will not be indexed by search engines. To make your private app public, read [Share your app](/streamlit-community-cloud/share-your-app).
-
-### Choose a custom subdomain early
-
-Streamlit Community Cloud automatically generates a random subdomain for your app. However, subdomains are customizable! Custom subdomains modify your app URLs to reflect your app content, personal branding, or whatever you’d like. Read more about custom subdomains in [Custom subdomains](/streamlit-community-cloud/deploy-your-app#custom-subdomains).
-
-By choosing a custom subdomain, you can use it to help people find your app. For example, if you're deploying an app that generates training data, you might choose a subdomain like `traingenerator.streamlit.app`. This makes it easy for people to find your app by searching for "training generator" or "train generator streamlit app."
-
-We recommend choosing a custom subdomain when you deploy your app. This ensures that your app is indexed by search engines using your custom subdomain, rather than the automatically generated one. If you choose a custom subdomain later, your app may be indexed multiple times—once using the default subdomain and once using your custom subdomain. In this case, your old URL will result in a 404 error which can confuse users who are searching for your app.
-
-### Choose a descriptive app title
-
-The meta title of your app is the text that appears in search engine results. It is also the text that appears in the browser tab when your app is open. By default, the meta title of your app is the same as the title of your app. However, you can customize the meta title of your app by setting the [`st.set_page_config`](/library/api-reference/utilities/st.set_page_config) parameter `page_title` to a custom string. For example:
-
-```python
-st.set_page_config(page_title="Traingenerator")
-```
-
-This will change the meta title of your app to "Traingenerator." This makes it easier for people to find your app by searching for "Traingenerator" or "train generator streamlit app":
-
-
-
-### Customize your app's meta description
-
-Meta descriptions are the short descriptions that appear in search engine results. Search engines use the meta description to help users understand what your app is about.
-
-From our observations, search engines seem to favor the content in both `st.header` and `st.text` over `st.title`. If you put a description at the top of your app under `st.header` or `st.text`, there’s a good chance search engines will use this for the meta description.
-
-## What does my indexed app look like?
-
-If you're curious about what your app looks like in search engine results, you can type the following into Google Search:
-
-```
-site:.streamlit.app
-```
-
-Example: `site:traingenerator.streamlit.app`
-
-
-
-## What if I don't want my app to be indexed?
-
-If you don't want your app to be indexed by search engines, you can make it private. Read [Share your app](/streamlit-community-cloud/share-your-app) to learn more about making your app private. Note: each workspace can only have one private app. If you want to make your app private, you must first delete any other private app in your workspace or make it public.
-
-That said, Streamlit Community Cloud is an open and free platform for the community to deploy, discover, and share Streamlit apps and code with each other. As such, we encourage you to make your app public so that it can be indexed by search engines and discovered by other Streamlit users and community members.
diff --git a/data/streamlit-cloud/share-your-app/share-previews.md b/data/streamlit-cloud/share-your-app/share-previews.md
deleted file mode 100644
index 8b3aa58ba..000000000
--- a/data/streamlit-cloud/share-your-app/share-previews.md
+++ /dev/null
@@ -1,64 +0,0 @@
----
-title: Share previews
-slug: /streamlit-community-cloud/share-your-app/share-previews
----
-
-# Share previews
-
-Social media sites generate a card with a title, preview image, and description when you share a link. This feature is called a "share preview." In the same way, when you share a link to a public Streamlit app on social media, a share preview is also generated. Here's an example of a share preview for a public Streamlit app posted on Twitter:
-
-
-
-
-
-
-
-
-
-Share previews are generated only for public apps deployed on Streamlit Community Cloud.
-
-
-
-## Titles
-
-The title is the text that appears at the top of the share preview. The text also appears in the browser tab when you visit the app. You should set the title to something that will make sense to your app's audience and describe what the app does. It is best practice to keep the title concise, ideally under 60 characters.
-
-There are two ways to set the title of a share preview:
-
-1. Set the `page_title` parameter in [`st.set_page_config()`](/library/api-reference/utilities/st.set_page_config) to your desired title. E.g.:
-
- ```python
- import streamlit as st
-
- st.set_page_config(page_title="My App")
-
- # ... rest of your app
- ```
-
-2. If you don't set the `page_title` parameter, the title of the share preview will be the name of your app's GitHub repository. For example, the default title for an app hosted on GitHub at github.com/jrieke/traingenerator will be "traingenerator".
-
-## Descriptions
-
-The description is the text that appears below the title in the share preview. The description should summarize what the app does and ideally should be under 100 characters.
-
-Streamlit pulls the description from the README in the app's GitHub repository. If there is no README, the description will default to:
-
-_This app was built in Streamlit! Check it out and visit https://streamlit.io for more awesome community apps. 🎈_
-
-
-
-
-
-
-
-
-
-If you want your share previews to look great and want users to share your app and click on your links, you should write a good description in the README of your app’s GitHub repository.
-
-## Preview images
-
-Streamlit Community Cloud takes a screenshot of your app once a day and uses it as the preview image, unlike titles and descriptions which are pulled directly from your app's code or GitHub repository. This screenshot may take up to 24 hours to update.
-
-### Switching your app from public to private
-
-If you initially made your app public and later decided to make it private, we will stop generating share previews for the app. However, it may take up to 24 hours for the share previews to stop appearing.
diff --git a/data/streamlit-cloud/troubleshooting.md b/data/streamlit-cloud/troubleshooting.md
deleted file mode 100644
index c3fd935c0..000000000
--- a/data/streamlit-cloud/troubleshooting.md
+++ /dev/null
@@ -1,156 +0,0 @@
----
-title: Troubleshooting
-slug: /streamlit-community-cloud/troubleshooting
----
-
-# Troubleshooting
-
-Sorry to hear you're having issues! Please take a look at some frequently asked questions and issues below. If you cannot find an answer to your issue, please post on our [Community forum](http://discuss.streamlit.io) so that our engineers or community members can help you.
-
-## Table of contents
-
-1. [General help](#general-help)
-2. [Deploying apps](#deploying-apps)
-3. [Sharing and accessing apps](/streamlit-community-cloud/troubleshooting#sharing-and-accessing-apps)
-4. [Data and app security](/streamlit-community-cloud/troubleshooting#data-and-app-security)
-5. [GitHub integration](/streamlit-community-cloud/troubleshooting#github-integration)
-6. [Limitations and known issues](/streamlit-community-cloud/troubleshooting#limitations-and-known-issues)
-
-## General help
-
-### How can I get help with my app?
-
-If you have any questions, feedback, run into any issues, or need to reach us, you can ask on our [Community forum](https://discuss.streamlit.io/). This is best suited for any questions related to the open source library and Community Cloud - debugging code, deployment, resource limits, etc.
-
-## Deploying apps
-
-### My repo isn't showing on the Deploy page
-
-It's possible it just isn't showing up even though it is already there. Try typing it in. If we don't recognize it, you'll see the message below with a link to click and give access.
-
-
-
-If for some reason that doesn't work, please try logging out and back in again to make sure the change took effect. And if that doesn't work - please let us know and we'll get you sorted!
-
-### It won't let me deploy the app
-
-To deploy an app for the first time you must have admin-level access to the repo in GitHub. Please check with your administrator to make sure you have that access. If not, please ask them to deploy for the first time (we need this in order to establish webhooks for continuous integration) and from there you can then push updates to the app.
-
-### I need to set a specific Python version for my app
-
-When deploying an app, under advanced settings, you can choose which version of Python you wish your app to use.
-
-
-
-### How do I store files locally?
-
-If you want to store your data locally as opposed to in a database, you can store the file in your GitHub repository. Streamlit is just python, so you can read the file using:
-
-`pandas.read_csv("data.csv")` or `open("data.csv")`
-
-
-
-If you have really big or binary data that you change frequently, and git is feeling slow, you might want to check out [Git Large File Store (LFS)](https://git-lfs.github.com/) as a better way to store large files in GitHub. You don't need to make any changes to your app to start using it. If your GitHub repo uses LFS, it will now _just work_ with Streamlit.
-
-
-
-### My app is running into issues while deploying
-
-Check your Cloud logs by clicking on the "Manage app" expander in the bottom right corner of your screen. Often the trouble is due to a dependency not being declared. See here for [more information on dependency management](/streamlit-community-cloud/deploy-your-app/app-dependencies).
-
-If that's not the issue, then please send the logs and warning you are seeing to our [Community forum](https://discuss.streamlit.io/) and we'll help get you sorted!
-
-### My app is hitting resource limits / my app is running very slowly
-
-If your app is running slowly or you're hitting the 'Argh' page, we first highly recommend going through and implementing the suggestions in the following blog posts to prevent your app from hitting the resource limits and to detect if your Streamlit app leaks memory:
-
-- [Common app problems: Resource limits](https://blog.streamlit.io/common-app-problems-resource-limits/)
-- [3 steps to fix app memory leaks](https://blog.streamlit.io/3-steps-to-fix-app-memory-leaks/)
-
-If you're still having issues, click [here](/streamlit-community-cloud/manage-your-app#app-resources-and-limits) to learn more about resource limits.
-
-### Can I get a custom URL for my app?
-
-Yes! You can find [instructions for setting a custom subdomain here](/knowledge-base/deploy/custom-subdomains).
-
-## Sharing and accessing apps
-
-
-
-### How do I add viewers to my Streamlit apps?
-
-Viewer auth allows you to restrict the viewers of your private app. To access your app, users have to authenticate using an email-based passwordless login or Google OAuth. To learn more about how to share your public and private apps with viewers, click [here](/streamlit-community-cloud/share-your-app).
-
-### Do viewers need access to the GitHub repo?
-
-Nope! You only need access to the GitHub repo if you want to push changes to the app.
-
-### What will unauthorized/logged out viewers see when they view my app?
-
-A 404 error is displayed to unauthorized viewers to avoid providing any unnecessary information about your app to unintended viewers. Users who satisfy any of the following conditions will see a 404 error when attempting to view your app after you have configured viewer auth:
-
-- User is not logged in with their primary identity.
-- User is not included in the [list of allowed viewers](/streamlit-community-cloud/share-your-app#share-your-private-app) provided in the app settings.
-- User lacks read access to your app's GitHub repo.
-- User has read access to your app's GitHub repo but is not enrolled in Streamlit Community Cloud.
-
-
-
-### I've added someone to the viewer list but they still see a 404 error when attempting to view the app
-
-If a user is still seeing a 404 error after their email address has been added to the viewer list, we recommend that you:
-
-- Check that the user did not log into a different Google account via Single Sign-On (if you have added their work email address to the viewer list, ask the user to check that they are not logged into their personal Google account, and vice versa).
-- Check that the user has navigated to the correct URL.
-- Check that the user's email address has been entered correctly in the viewer list.
-
-- Reach out on our [Community forum](https://discuss.streamlit.io/) and we will be happy to help.
-
-## Data and app security
-
-### How will Streamlit secure my data?
-
-Streamlit takes a number of industry best-practice measures to ensure your code, data, and apps are all secure. Read more in our [Trust and Security memo](/streamlit-community-cloud/get-started/trust-and-security).
-
-### How do I set up SSO for my organization?
-
-Community Cloud uses Google OAuth, by default. If you use Google for authentication you're all set.
-
-## Billing and administration
-
-The Community Cloud is a free service. You don't have to worry about setting up billing or being charged.
-
-## GitHub integration
-
-### Why does Streamlit require additional OAuth scope?
-
-In order to deploy your app, Streamlit requires access to your app's source code in GitHub and also the ability to manage the public keys associated with the repositories. The default GitHub OAuth scopes are sufficient to work with apps in public GitHub repositories. However, in order to work with apps in private GitHub repositories, Streamlit requires the additional `repo` OAuth scope from GitHub. We recognize that this scope provides Streamlit with extra permissions that we do not really need, and which, as people who prize security, we'd rather not even be granted. Alas, we need to work with the APIs we are provided by GitHub.
-
-### After deploying my private-repo app, I received an email from GitHub saying a new public key was added to my repo. Is this expected?
-
-**This is the expected behavior**. When you try to deploy an app that lives in a private repo, Streamlit Community Cloud needs to get access to that repo somehow. For this, we create a read-only [GitHub Deploy Key](https://docs.github.com/en/free-pro-team@latest/developers/overview/managing-deploy-keys#deploy-keys) then access your repo using a public SSH key. When we set this up, GitHub notifies admins of the repo that the key was created as a security measure.
-
-### What happens when a user's permissions change on GitHub?
-
-Once a user is added to a repository on GitHub, it will take at most 15 minutes before they can deploy the app on Cloud. If a user is removed from a repository on GitHub, it will take at most 15 minutes before their permissions to manage the app from that repository are revoked.
-
-## Limitations and known issues
-
-Here are some limitations and known issues that we're actively working to resolve.
-
-- When you print something to the Cloud logs, you may need to do a `sys.stdout.flush()` before it shows up.
-- Matplotlib [doesn't work well with threads](https://matplotlib.org/3.3.2/faq/howto_faq.html#working-with-threads). So if you're using Matplotlib you should wrap your code with locks as shown in the snippet below. This Matplotlib bug is more prominent when you share your app apps since you're more likely to get more concurrent users then.
-
- ```python
- from matplotlib.backends.backend_agg import RendererAgg
- _lock = RendererAgg.lock
-
- with _lock:
- fig.title('This is a figure)')
- fig.plot([1,20,3,40])
- st.pyplot(fig)
- ```
-
-- All apps are hosted in the United States. This is currently not configurable.
diff --git a/data/terms_definitions_tutorial.md b/data/terms_definitions_tutorial.md
deleted file mode 100644
index 98f79ee68..000000000
--- a/data/terms_definitions_tutorial.md
+++ /dev/null
@@ -1,487 +0,0 @@
-# A Guide to Extracting Terms and Definitions
-
-Llama Index has many use cases (semantic search, summarization, etc.) that are [well documented](/end_to_end_tutorials/use_cases.md). However, this doesn't mean we can't apply Llama Index to very specific use cases!
-
-In this tutorial, we will go through the design process of using Llama Index to extract terms and definitions from text, while allowing users to query those terms later. Using [Streamlit](https://streamlit.io/), we can provide an easy way to build frontend for running and testing all of this, and quickly iterate with our design.
-
-This tutorial assumes you have Python3.9+ and the following packages installed:
-
-- llama-index
-- streamlit
-
-At the base level, our objective is to take text from a document, extract terms and definitions, and then provide a way for users to query that knowledge base of terms and definitions. The tutorial will go over features from both Llama Index and Streamlit, and hopefully provide some interesting solutions for common problems that come up.
-
-The final version of this tutorial can be found [here](https://github.com/logan-markewich/llama_index_starter_pack) and a live hosted demo is available on [Huggingface Spaces](https://huggingface.co/spaces/llamaindex/llama_index_term_definition_demo).
-
-## Uploading Text
-
-Step one is giving users a way to upload documents. Let’s write some code using Streamlit to provide the interface for this! Use the following code and launch the app with `streamlit run app.py`.
-
-```python
-import streamlit as st
-
-st.title("🦙 Llama Index Term Extractor 🦙")
-
-document_text = st.text_area("Or enter raw text")
-if st.button("Extract Terms and Definitions") and document_text:
- with st.spinner("Extracting..."):
- extracted_terms = document text # this is a placeholder!
- st.write(extracted_terms)
-```
-
-Super simple right! But you'll notice that the app doesn't do anything useful yet. To use llama_index, we also need to setup our OpenAI LLM. There are a bunch of possible settings for the LLM, so we can let the user figure out what's best. We should also let the user set the prompt that will extract the terms (which will also help us debug what works best).
-
-## LLM Settings
-
-This next step introduces some tabs to our app, to separate it into different panes that provide different features. Let's create a tab for LLM settings and for uploading text:
-
-```python
-import os
-import streamlit as st
-
-DEFAULT_TERM_STR = (
- "Make a list of terms and definitions that are defined in the context, "
- "with one pair on each line. "
- "If a term is missing it's definition, use your best judgment. "
- "Write each line as as follows:\nTerm: Definition: "
-)
-
-st.title("🦙 Llama Index Term Extractor 🦙")
-
-setup_tab, upload_tab = st.tabs(["Setup", "Upload/Extract Terms"])
-
-with setup_tab:
- st.subheader("LLM Setup")
- api_key = st.text_input("Enter your OpenAI API key here", type="password")
- llm_name = st.selectbox('Which LLM?', ["text-davinci-003", "gpt-3.5-turbo", "gpt-4"])
- model_temperature = st.slider("LLM Temperature", min_value=0.0, max_value=1.0, step=0.1)
- term_extract_str = st.text_area("The query to extract terms and definitions with.", value=DEFAULT_TERM_STR)
-
-with upload_tab:
- st.subheader("Extract and Query Definitions")
- document_text = st.text_area("Or enter raw text")
- if st.button("Extract Terms and Definitions") and document_text:
- with st.spinner("Extracting..."):
- extracted_terms = document text # this is a placeholder!
- st.write(extracted_terms)
-```
-
-Now our app has two tabs, which really helps with the organization. You'll also noticed I added a default prompt to extract terms -- you can change this later once you try extracting some terms, it's just the prompt I arrived at after experimenting a bit.
-
-Speaking of extracting terms, it's time to add some functions to do just that!
-
-## Extracting and Storing Terms
-
-Now that we are able to define LLM settings and upload text, we can try using Llama Index to extract the terms from text for us!
-
-We can add the following functions to both initialize our LLM, as well as use it to extract terms from the input text.
-
-```python
-from llama_index import Document, ListIndex, LLMPredictor, ServiceContext, load_index_from_storage
-from llama_index.llms import OpenAI
-
-def get_llm(llm_name, model_temperature, api_key, max_tokens=256):
- os.environ['OPENAI_API_KEY'] = api_key
- return OpenAI(temperature=model_temperature, model=llm_name, max_tokens=max_tokens)
-
-def extract_terms(documents, term_extract_str, llm_name, model_temperature, api_key):
- llm = get_llm(llm_name, model_temperature, api_key, max_tokens=1024)
-
- service_context = ServiceContext.from_defaults(llm=llm,
- chunk_size=1024)
-
- temp_index = ListIndex.from_documents(documents, service_context=service_context)
- query_engine = temp_index.as_query_engine(response_mode="tree_summarize")
- terms_definitions = str(query_engine.query(term_extract_str))
- terms_definitions = [x for x in terms_definitions.split("\n") if x and 'Term:' in x and 'Definition:' in x]
- # parse the text into a dict
- terms_to_definition = {x.split("Definition:")[0].split("Term:")[-1].strip(): x.split("Definition:")[-1].strip() for x in terms_definitions}
- return terms_to_definition
-```
-
-Now, using the new functions, we can finally extract our terms!
-
-```python
-...
-with upload_tab:
- st.subheader("Extract and Query Definitions")
- document_text = st.text_area("Or enter raw text")
- if st.button("Extract Terms and Definitions") and document_text:
- with st.spinner("Extracting..."):
- extracted_terms = extract_terms([Document(text=document_text)],
- term_extract_str, llm_name,
- model_temperature, api_key)
- st.write(extracted_terms)
-```
-
-There's a lot going on now, let's take a moment to go over what is happening.
-
-`get_llm()` is instantiating the LLM based on the user configuration from the setup tab. Based on the model name, we need to use the appropriate class (`OpenAI` vs. `ChatOpenAI`).
-
-`extract_terms()` is where all the good stuff happens. First, we call `get_llm()` with `max_tokens=1024`, since we don't want to limit the model too much when it is extracting our terms and definitions (the default is 256 if not set). Then, we define our `ServiceContext` object, aligning `num_output` with our `max_tokens` value, as well as setting the chunk size to be no larger than the output. When documents are indexed by Llama Index, they are broken into chunks (also called nodes) if they are large, and `chunk_size` sets the size for these chunks.
-
-Next, we create a temporary list index and pass in our service context. A list index will read every single piece of text in our index, which is perfect for extracting terms. Finally, we use our pre-defined query text to extract terms, using `response_mode="tree_summarize`. This response mode will generate a tree of summaries from the bottom up, where each parent summarizes its children. Finally, the top of the tree is returned, which will contain all our extracted terms and definitions.
-
-Lastly, we do some minor post processing. We assume the model followed instructions and put a term/definition pair on each line. If a line is missing the `Term:` or `Definition:` labels, we skip it. Then, we convert this to a dictionary for easy storage!
-
-## Saving Extracted Terms
-
-Now that we can extract terms, we need to put them somewhere so that we can query for them later. A `VectorStoreIndex` should be a perfect choice for now! But in addition, our app should also keep track of which terms are inserted into the index so that we can inspect them later. Using `st.session_state`, we can store the current list of terms in a session dict, unique to each user!
-
-First things first though, let's add a feature to initialize a global vector index and another function to insert the extracted terms.
-
-```python
-...
-if 'all_terms' not in st.session_state:
- st.session_state['all_terms'] = DEFAULT_TERMS
-...
-
-def insert_terms(terms_to_definition):
- for term, definition in terms_to_definition.items():
- doc = Document(text=f"Term: {term}\nDefinition: {definition}")
- st.session_state['llama_index'].insert(doc)
-
-@st.cache_resource
-def initialize_index(llm_name, model_temperature, api_key):
- """Create the VectorStoreIndex object."""
- llm = get_llm(llm_name, model_temperature, api_key)
-
- service_context = ServiceContext.from_defaults(llm=llm)
-
- index = VectorStoreIndex([], service_context=service_context)
-
- return index
-
-...
-
-with upload_tab:
- st.subheader("Extract and Query Definitions")
- if st.button("Initialize Index and Reset Terms"):
- st.session_state['llama_index'] = initialize_index(llm_name, model_temperature, api_key)
- st.session_state['all_terms'] = {}
-
- if "llama_index" in st.session_state:
- st.markdown("Either upload an image/screenshot of a document, or enter the text manually.")
- document_text = st.text_area("Or enter raw text")
- if st.button("Extract Terms and Definitions") and (uploaded_file or document_text):
- st.session_state['terms'] = {}
- terms_docs = {}
- with st.spinner("Extracting..."):
- terms_docs.update(extract_terms([Document(text=document_text)], term_extract_str, llm_name, model_temperature, api_key))
- st.session_state['terms'].update(terms_docs)
-
- if "terms" in st.session_state and st.session_state["terms"]::
- st.markdown("Extracted terms")
- st.json(st.session_state['terms'])
-
- if st.button("Insert terms?"):
- with st.spinner("Inserting terms"):
- insert_terms(st.session_state['terms'])
- st.session_state['all_terms'].update(st.session_state['terms'])
- st.session_state['terms'] = {}
- st.experimental_rerun()
-```
-
-Now you are really starting to leverage the power of streamlit! Let's start with the code under the upload tab. We added a button to initialize the vector index, and we store it in the global streamlit state dictionary, as well as resetting the currently extracted terms. Then, after extracting terms from the input text, we store it the extracted terms in the global state again and give the user a chance to review them before inserting. If the insert button is pressed, then we call our insert terms function, update our global tracking of inserted terms, and remove the most recently extracted terms from the session state.
-
-## Querying for Extracted Terms/Definitions
-
-With the terms and definitions extracted and saved, how can we use them? And how will the user even remember what's previously been saved?? We can simply add some more tabs to the app to handle these features.
-
-```python
-...
-setup_tab, terms_tab, upload_tab, query_tab = st.tabs(
- ["Setup", "All Terms", "Upload/Extract Terms", "Query Terms"]
-)
-...
-with terms_tab:
- with terms_tab:
- st.subheader("Current Extracted Terms and Definitions")
- st.json(st.session_state["all_terms"])
-...
-with query_tab:
- st.subheader("Query for Terms/Definitions!")
- st.markdown(
- (
- "The LLM will attempt to answer your query, and augment it's answers using the terms/definitions you've inserted. "
- "If a term is not in the index, it will answer using it's internal knowledge."
- )
- )
- if st.button("Initialize Index and Reset Terms", key="init_index_2"):
- st.session_state["llama_index"] = initialize_index(
- llm_name, model_temperature, api_key
- )
- st.session_state["all_terms"] = {}
-
- if "llama_index" in st.session_state:
- query_text = st.text_input("Ask about a term or definition:")
- if query_text:
- query_text = query_text + "\nIf you can't find the answer, answer the query with the best of your knowledge."
- with st.spinner("Generating answer..."):
- response = st.session_state["llama_index"].query(
- query_text, similarity_top_k=5, response_mode="compact"
- )
- st.markdown(str(response))
-```
-
-While this is mostly basic, some important things to note:
-
-- Our initialize button has the same text as our other button. Streamlit will complain about this, so we provide a unique key instead.
-- Some additional text has been added to the query! This is to try and compensate for times when the index does not have the answer.
-- In our index query, we've specified two options:
- - `similarity_top_k=5` means the index will fetch the top 5 closest matching terms/definitions to the query.
- - `response_mode="compact"` means as much text as possible from the 5 matching terms/definitions will be used in each LLM call. Without this, the index would make at least 5 calls to the LLM, which can slow things down for the user.
-
-## Dry Run Test
-
-Well, actually I hope you've been testing as we went. But now, let's try one complete test.
-
-1. Refresh the app
-2. Enter your LLM settings
-3. Head over to the query tab
-4. Ask the following: `What is a bunnyhug?`
-5. The app should give some nonsense response. If you didn't know, a bunnyhug is another word for a hoodie, used by people from the Canadian Prairies!
-6. Let's add this definition to the app. Open the upload tab and enter the following text: `A bunnyhug is a common term used to describe a hoodie. This term is used by people from the Canadian Prairies.`
-7. Click the extract button. After a few moments, the app should display the correctly extracted term/definition. Click the insert term button to save it!
-8. If we open the terms tab, the term and definition we just extracted should be displayed
-9. Go back to the query tab and try asking what a bunnyhug is. Now, the answer should be correct!
-
-## Improvement #1 - Create a Starting Index
-
-With our base app working, it might feel like a lot of work to build up a useful index. What if we gave the user some kind of starting point to show off the app's query capabilities? We can do just that! First, let's make a small change to our app so that we save the index to disk after every upload:
-
-```python
-def insert_terms(terms_to_definition):
- for term, definition in terms_to_definition.items():
- doc = Document(text=f"Term: {term}\nDefinition: {definition}")
- st.session_state['llama_index'].insert(doc)
- # TEMPORARY - save to disk
- st.session_state['llama_index'].storage_context.persist()
-```
-
-Now, we need some document to extract from! The repository for this project used the wikipedia page on New York City, and you can find the text [here](https://github.com/jerryjliu/llama_index/blob/main/examples/test_wiki/data/nyc_text.txt).
-
-If you paste the text into the upload tab and run it (it may take some time), we can insert the extracted terms. Make sure to also copy the text for the extracted terms into a notepad or similar before inserting into the index! We will need them in a second.
-
-After inserting, remove the line of code we used to save the index to disk. With a starting index now saved, we can modify our `initialize_index` function to look like this:
-
-```python
-@st.cache_resource
-def initialize_index(llm_name, model_temperature, api_key):
- """Load the Index object."""
- llm = get_llm(llm_name, model_temperature, api_key)
-
- service_context = ServiceContext.from_defaults(llm=llm)
-
- index = load_index_from_storage(service_context=service_context)
-
- return index
-```
-
-Did you remember to save that giant list of extracted terms in a notepad? Now when our app initializes, we want to pass in the default terms that are in the index to our global terms state:
-
-```python
-...
-if "all_terms" not in st.session_state:
- st.session_state["all_terms"] = DEFAULT_TERMS
-...
-```
-
-Repeat the above anywhere where we were previously resetting the `all_terms` values.
-
-## Improvement #2 - (Refining) Better Prompts
-
-If you play around with the app a bit now, you might notice that it stopped following our prompt! Remember, we added to our `query_str` variable that if the term/definition could not be found, answer to the best of its knowledge. But now if you try asking about random terms (like bunnyhug!), it may or may not follow those instructions.
-
-This is due to the concept of "refining" answers in Llama Index. Since we are querying across the top 5 matching results, sometimes all the results do not fit in a single prompt! OpenAI models typically have a max input size of 4097 tokens. So, Llama Index accounts for this by breaking up the matching results into chunks that will fit into the prompt. After Llama Index gets an initial answer from the first API call, it sends the next chunk to the API, along with the previous answer, and asks the model to refine that answer.
-
-So, the refine process seems to be messing with our results! Rather than appending extra instructions to the `query_str`, remove that, and Llama Index will let us provide our own custom prompts! Let's create those now, using the [default prompts](https://github.com/jerryjliu/llama_index/blob/main/llama_index/prompts/default_prompts.py) and [chat specific prompts](https://github.com/jerryjliu/llama_index/blob/main/llama_index/prompts/chat_prompts.py) as a guide. Using a new file `constants.py`, let's create some new query templates:
-
-```python
-from langchain.chains.prompt_selector import ConditionalPromptSelector, is_chat_model
-from langchain.prompts.chat import (
- AIMessagePromptTemplate,
- ChatPromptTemplate,
- HumanMessagePromptTemplate,
-)
-
-from llama_index.prompts.prompts import QuestionAnswerPrompt, RefinePrompt
-
-# Text QA templates
-DEFAULT_TEXT_QA_PROMPT_TMPL = (
- "Context information is below. \n"
- "---------------------\n"
- "{context_str}"
- "\n---------------------\n"
- "Given the context information answer the following question "
- "(if you don't know the answer, use the best of your knowledge): {query_str}\n"
-)
-TEXT_QA_TEMPLATE = QuestionAnswerPrompt(DEFAULT_TEXT_QA_PROMPT_TMPL)
-
-# Refine templates
-DEFAULT_REFINE_PROMPT_TMPL = (
- "The original question is as follows: {query_str}\n"
- "We have provided an existing answer: {existing_answer}\n"
- "We have the opportunity to refine the existing answer "
- "(only if needed) with some more context below.\n"
- "------------\n"
- "{context_msg}\n"
- "------------\n"
- "Given the new context and using the best of your knowledge, improve the existing answer. "
- "If you can't improve the existing answer, just repeat it again."
-)
-DEFAULT_REFINE_PROMPT = RefinePrompt(DEFAULT_REFINE_PROMPT_TMPL)
-
-CHAT_REFINE_PROMPT_TMPL_MSGS = [
- HumanMessagePromptTemplate.from_template("{query_str}"),
- AIMessagePromptTemplate.from_template("{existing_answer}"),
- HumanMessagePromptTemplate.from_template(
- "We have the opportunity to refine the above answer "
- "(only if needed) with some more context below.\n"
- "------------\n"
- "{context_msg}\n"
- "------------\n"
- "Given the new context and using the best of your knowledge, improve the existing answer. "
- "If you can't improve the existing answer, just repeat it again."
- ),
-]
-
-CHAT_REFINE_PROMPT_LC = ChatPromptTemplate.from_messages(CHAT_REFINE_PROMPT_TMPL_MSGS)
-CHAT_REFINE_PROMPT = RefinePrompt.from_langchain_prompt(CHAT_REFINE_PROMPT_LC)
-
-# refine prompt selector
-DEFAULT_REFINE_PROMPT_SEL_LC = ConditionalPromptSelector(
- default_prompt=DEFAULT_REFINE_PROMPT.get_langchain_prompt(),
- conditionals=[(is_chat_model, CHAT_REFINE_PROMPT.get_langchain_prompt())],
-)
-REFINE_TEMPLATE = RefinePrompt(
- langchain_prompt_selector=DEFAULT_REFINE_PROMPT_SEL_LC
-)
-```
-
-That seems like a lot of code, but it's not too bad! If you looked at the default prompts, you might have noticed that there are default prompts, and prompts specific to chat models. Continuing that trend, we do the same for our custom prompts. Then, using a prompt selector, we can combine both prompts into a single object. If the LLM being used is a chat model (ChatGPT, GPT-4), then the chat prompts are used. Otherwise, use the normal prompt templates.
-
-Another thing to note is that we only defined one QA template. In a chat model, this will be converted to a single "human" message.
-
-So, now we can import these prompts into our app and use them during the query.
-
-```python
-from constants import REFINE_TEMPLATE, TEXT_QA_TEMPLATE
-...
- if "llama_index" in st.session_state:
- query_text = st.text_input("Ask about a term or definition:")
- if query_text:
- query_text = query_text # Notice we removed the old instructions
- with st.spinner("Generating answer..."):
- response = st.session_state["llama_index"].query(
- query_text, similarity_top_k=5, response_mode="compact",
- text_qa_template=TEXT_QA_TEMPLATE, refine_template=REFINE_TEMPLATE
- )
- st.markdown(str(response))
-...
-```
-
-If you experiment a bit more with queries, hopefully you notice that the responses follow our instructions a little better now!
-
-## Improvement #3 - Image Support
-
-Llama index also supports images! Using Llama Index, we can upload images of documents (papers, letters, etc.), and Llama Index handles extracting the text. We can leverage this to also allow users to upload images of their documents and extract terms and definitions from them.
-
-If you get an import error about PIL, install it using `pip install Pillow` first.
-
-```python
-from PIL import Image
-from llama_index.readers.file.base import DEFAULT_FILE_EXTRACTOR, ImageParser
-
-@st.cache_resource
-def get_file_extractor():
- image_parser = ImageParser(keep_image=True, parse_text=True)
- file_extractor = DEFAULT_FILE_EXTRACTOR
- file_extractor.update(
- {
- ".jpg": image_parser,
- ".png": image_parser,
- ".jpeg": image_parser,
- }
- )
-
- return file_extractor
-
-file_extractor = get_file_extractor()
-...
-with upload_tab:
- st.subheader("Extract and Query Definitions")
- if st.button("Initialize Index and Reset Terms", key="init_index_1"):
- st.session_state["llama_index"] = initialize_index(
- llm_name, model_temperature, api_key
- )
- st.session_state["all_terms"] = DEFAULT_TERMS
-
- if "llama_index" in st.session_state:
- st.markdown(
- "Either upload an image/screenshot of a document, or enter the text manually."
- )
- uploaded_file = st.file_uploader(
- "Upload an image/screenshot of a document:", type=["png", "jpg", "jpeg"]
- )
- document_text = st.text_area("Or enter raw text")
- if st.button("Extract Terms and Definitions") and (
- uploaded_file or document_text
- ):
- st.session_state["terms"] = {}
- terms_docs = {}
- with st.spinner("Extracting (images may be slow)..."):
- if document_text:
- terms_docs.update(
- extract_terms(
- [Document(text=document_text)],
- term_extract_str,
- llm_name,
- model_temperature,
- api_key,
- )
- )
- if uploaded_file:
- Image.open(uploaded_file).convert("RGB").save("temp.png")
- img_reader = SimpleDirectoryReader(
- input_files=["temp.png"], file_extractor=file_extractor
- )
- img_docs = img_reader.load_data()
- os.remove("temp.png")
- terms_docs.update(
- extract_terms(
- img_docs,
- term_extract_str,
- llm_name,
- model_temperature,
- api_key,
- )
- )
- st.session_state["terms"].update(terms_docs)
-
- if "terms" in st.session_state and st.session_state["terms"]:
- st.markdown("Extracted terms")
- st.json(st.session_state["terms"])
-
- if st.button("Insert terms?"):
- with st.spinner("Inserting terms"):
- insert_terms(st.session_state["terms"])
- st.session_state["all_terms"].update(st.session_state["terms"])
- st.session_state["terms"] = {}
- st.experimental_rerun()
-```
-
-Here, we added the option to upload a file using Streamlit. Then the image is opened and saved to disk (this seems hacky but it keeps things simple). Then we pass the image path to the reader, extract the documents/text, and remove our temp image file.
-
-Now that we have the documents, we can call `extract_terms()` the same as before.
-
-## Conclusion/TLDR
-
-In this tutorial, we covered a ton of information, while solving some common issues and problems along the way:
-
-- Using different indexes for different use cases (List vs. Vector index)
-- Storing global state values with Streamlit's `session_state` concept
-- Customizing internal prompts with Llama Index
-- Reading text from images with Llama Index
-
-The final version of this tutorial can be found [here](https://github.com/logan-markewich/llama_index_starter_pack) and a live hosted demo is available on [Huggingface Spaces](https://huggingface.co/spaces/llamaindex/llama_index_term_definition_demo).
diff --git a/streamlit_app.py b/streamlit_app.py
index 936188245..e90d9bf11 100644
--- a/streamlit_app.py
+++ b/streamlit_app.py
@@ -1,45 +1,114 @@
+import os
+os.environ["TIKTOKEN_CACHE_DIR"] = "/tmp"
import streamlit as st
-from llama_index import VectorStoreIndex, ServiceContext, Document
-from llama_index.llms import OpenAI
-import openai
-from llama_index import SimpleDirectoryReader
-
-st.set_page_config(page_title="Chat with the Streamlit docs, powered by LlamaIndex", page_icon="🦙", layout="centered", initial_sidebar_state="auto", menu_items=None)
-openai.api_key = st.secrets.openai_key
-st.title("Chat with the Streamlit docs, powered by LlamaIndex 💬🦙")
-st.info("Check out the full tutorial to build this app in our [blog post](https://blog.streamlit.io/build-a-chatbot-with-custom-data-sources-powered-by-llamaindex/)", icon="📃")
-
-if "messages" not in st.session_state.keys(): # Initialize the chat messages history
+from llama_index.llms.gemini import Gemini
+from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
+from llama_index.embeddings.gemini import GeminiEmbedding
+
+from llama_index.embeddings.google_genai import GoogleGenAIEmbedding
+from google.genai.types import EmbedContentConfig
+
+import nltk
+
+@st.cache_data
+def get_stopwords():
+ nltk.download('stopwords')
+
+st.set_page_config(page_title="Chat with a friend on Quantitative Physics", page_icon="🦙", layout="centered", initial_sidebar_state="auto", menu_items=None)
+st.title("Ask Me a Question about Quantitative Physics")
+
+
+if "messages" not in st.session_state.keys(): # Initialize the chat messages history
st.session_state.messages = [
- {"role": "assistant", "content": "Ask me a question about Streamlit's open-source Python library!"}
+ {
+ "role": "assistant",
+ "content": "Ask me a question about Quantitative Physics!!",
+ }
]
@st.cache_resource(show_spinner=False)
def load_data():
- with st.spinner(text="Loading and indexing the Streamlit docs – hang tight! This should take 1-2 minutes."):
- reader = SimpleDirectoryReader(input_dir="./data", recursive=True)
- docs = reader.load_data()
- service_context = ServiceContext.from_defaults(llm=OpenAI(model="gpt-3.5-turbo", temperature=0.5, system_prompt="You are an expert on the Streamlit Python library and your job is to answer technical questions. Assume that all questions are related to the Streamlit Python library. Keep your answers technical and based on facts – do not hallucinate features."))
- index = VectorStoreIndex.from_documents(docs, service_context=service_context)
- return index
+ reader = SimpleDirectoryReader(input_dir="./data", recursive=True)
+ docs = reader.load_data()
+
+ Settings.chunk_size = 1500
+ Settings.chunk_overlap = 50
+ Settings.embed_model = GoogleGenAIEmbedding(
+ model_name="text-embedding-004",
+ embed_batch_size=100,
+ api_key=st.secrets.google_gemini_key,
+ )
+
+
+ Settings.llm = Gemini(
+ model="models/gemini-2.5-flash",
+ temperature=1.0,
+ system_prompt="""You are an expert on Quantitative Physics.
+ Answer the question using the provided documents, which contain relevant textbook text.
+ The context for all questions is the field of Quantitative Physics. Whenever possible, include a quotation from the provided excerpts of the work to illustrate your point.
+ Respond using a educational but direct tone, typical of a high school teacher.
+ Keep your answers under 500 words.""",
+ api_key = st.secrets.google_gemini_key,
+ safe = [
+ {
+ "category": "HARM_CATEGORY_HARASSMENT",
+ "threshold": "BLOCK_ONLY_HIGH",
+ },
+ {
+ "category": "HARM_CATEGORY_HATE_SPEECH",
+ "threshold": "BLOCK_ONLY_HIGH",
+ },
+ {
+ "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
+ "threshold": "BLOCK_ONLY_HIGH",
+ },
+ {
+ "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
+ "threshold": "BLOCK_ONLY_HIGH",
+ },
+],
+ )
+
+
+ index = VectorStoreIndex.from_documents(docs)
+ return index
+
index = load_data()
-if "chat_engine" not in st.session_state.keys(): # Initialize the chat engine
- st.session_state.chat_engine = index.as_chat_engine(chat_mode="condense_question", verbose=True)
+if "chat_engine" not in st.session_state.keys(): # Initialize the chat engine
+ st.session_state.chat_engine = index.as_chat_engine(
+ chat_mode="condense_plus_context", verbose=True, streaming=False,
+ )
-if prompt := st.chat_input("Your question"): # Prompt for user input and save to chat history
+if prompt := st.chat_input(
+ "Ask a question"
+): # Prompt for user input and save to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
-for message in st.session_state.messages: # Display the prior chat messages
+for message in st.session_state.messages: # Write message history to UI
with st.chat_message(message["role"]):
st.write(message["content"])
# If last message is not from assistant, generate a new response
if st.session_state.messages[-1]["role"] != "assistant":
with st.chat_message("assistant"):
- with st.spinner("Thinking..."):
- response = st.session_state.chat_engine.chat(prompt)
- st.write(response.response)
- message = {"role": "assistant", "content": response.response}
- st.session_state.messages.append(message) # Add response to message history
+ response_stream = ""
+ try:
+ response_stream = st.session_state.chat_engine.stream_chat(prompt)
+ except:
+ st.error("We got an error from Google Gemini - this may mean the question had a risk of producing a harmful response. Consider asking the question in a different way.")
+ if response_stream != "":
+ with st.spinner("waiting"):
+ try:
+ st.write_stream(response_stream.response_gen)
+ except:
+ st.error("We hit a bump - let's try again")
+ try:
+ resp = st.session_state.chat_engine.chat(prompt)[0]
+ st.write(resp)
+ except:
+ st.error("We got an error from Google Gemini - this may mean the question had a risk of producing a harmful response. Consider asking the question in a different way.")
+ message = {"role": "assistant", "content": response_stream.response}
+ # Add response to message history
+ st.session_state.messages.append(message)