Skip to content

Commit 99070f7

Browse files
Update supabase and postgresql tutorials for st.connection (#812)
* Update supabase tutorial for st.connection * Update postgresql tutorial for st.connection * Update content/kb/tutorials/databases/postgresql.md Co-authored-by: Debbie Matthews <[email protected]> * Implement feedback --------- Co-authored-by: Debbie Matthews <[email protected]>
1 parent 4e54057 commit 99070f7

File tree

2 files changed

+100
-49
lines changed

2 files changed

+100
-49
lines changed

content/kb/tutorials/databases/postgresql.md

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ slug: /knowledge-base/tutorials/databases/postgresql
77

88
## Introduction
99

10-
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).
10+
This guide explains how to securely access a **_remote_** PostgreSQL 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.
1111

1212
## Create a PostgreSQL database
1313

@@ -36,17 +36,18 @@ Your local Streamlit app will read secrets from a file `.streamlit/secrets.toml`
3636
```toml
3737
# .streamlit/secrets.toml
3838

39-
[postgres]
39+
[connections.postgresql]
40+
dialect = "postgresql"
4041
host = "localhost"
41-
port = 5432
42-
dbname = "xxx"
43-
user = "xxx"
42+
port = "5432"
43+
database = "xxx"
44+
username = "xxx"
4445
password = "xxx"
4546
```
4647

4748
<Important>
4849

49-
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!
50+
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_ PostgreSQL database!
5051

5152
Add this file to `.gitignore` and don't commit it to your GitHub repo!
5253

@@ -58,13 +59,14 @@ As the `secrets.toml` file above is not committed to GitHub, you need to pass it
5859

5960
![Secrets manager screenshot](/images/databases/edit-secrets.png)
6061

61-
## Add psycopg2 to your requirements file
62+
## Add dependencies to your requirements file
6263

63-
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):
64+
Add the [psycopg2-binary](https://www.psycopg.org/) 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):
6465

6566
```bash
6667
# requirements.txt
6768
psycopg2-binary==x.x.x
69+
sqlalchemy==x.x.x
6870
```
6971

7072
## Write your Streamlit app
@@ -75,32 +77,19 @@ Copy the code below to your Streamlit app and run it. Make sure to adapt `query`
7577
# streamlit_app.py
7678

7779
import streamlit as st
78-
import psycopg2
7980

8081
# Initialize connection.
81-
# Uses st.cache_resource to only run once.
82-
@st.cache_resource
83-
def init_connection():
84-
return psycopg2.connect(**st.secrets["postgres"])
85-
86-
conn = init_connection()
82+
conn = st.experimental_connection("postgresql", type="sql")
8783

8884
# Perform query.
89-
# Uses st.cache_data to only rerun when the query changes or after 10 min.
90-
@st.cache_data(ttl=600)
91-
def run_query(query):
92-
with conn.cursor() as cur:
93-
cur.execute(query)
94-
return cur.fetchall()
95-
96-
rows = run_query("SELECT * from mytable;")
85+
df = conn.query('SELECT * FROM mytable;', ttl="10m")
9786

9887
# Print results.
99-
for row in rows:
100-
st.write(f"{row[0]} has a :{row[1]}:")
88+
for row in df.itertuples():
89+
st.write(f"{row.name} has a :{row.pet}:")
10190
```
10291

103-
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).
92+
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="10m"` 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).
10493

10594
If everything worked out (and you used the example table we created above), your app should look like this:
10695

content/kb/tutorials/databases/supabase.md

Lines changed: 85 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ slug: /knowledge-base/tutorials/databases/supabase
77

88
## Introduction
99

10-
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.
10+
This guide explains how to securely access a Supabase instance from Streamlit Community Cloud. It uses [st.experimental_connection](/library/api-reference/connections/st.experimental_connection), [Streamlit Supabase Connector](https://github.com/SiddhantSadangi/st_supabase_connection/tree/main) (a community-built connection developed by [@SiddhantSadangi](https://github.com/SiddhantSadangi)) 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.
11+
12+
<Note>
13+
14+
Community-built connections, such as the [Streamlit Supabase Connector](https://github.com/SiddhantSadangi/st_supabase_connection/tree/main), extend and build on the `st.experimental_connection` interface and make it easier than ever to build Streamlit apps with a wide variety of data sources. These type of connections work exactly the same as [the ones built into Streamlit](/library/api-reference/connections) and have access to all the same capabilities.
15+
16+
</Note>
1117

1218
## Sign in to Supabase and create a project
1319

@@ -68,13 +74,14 @@ With your Supabase database created, you can now connect to it from Streamlit!
6874

6975
### Add Supabase Project URL and API key to your local app secrets
7076

71-
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:
77+
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:
7278

7379
```toml
7480
# .streamlit/secrets.toml
7581

76-
supabase_url = "xxxx"
77-
supabase_key = "xxxx"
82+
[connections.supabase]
83+
SUPABASE_URL = "xxxx"
84+
SUPABASE_KEY = "xxxx"
7885
```
7986

8087
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).
@@ -91,15 +98,23 @@ As the `secrets.toml` file above is not committed to GitHub, you need to pass it
9198

9299
![Secrets manager screenshot](/images/databases/edit-secrets.png)
93100

94-
## Add supabase to your requirements file
101+
## Add st-supabase-connection to your requirements file
95102

96-
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):
103+
Add the [`st-supabase-connection`](https://pypi.org/project/st-supabase-connection/) community-built connection library to your `requirements.txt` file, preferably pinning its version (replace `x.x.x` with the version you want installed):
97104

98105
```bash
99106
# requirements.txt
100-
supabase==x.x.x
107+
st-supabase-connection==x.x.x
101108
```
102109

110+
<Tip>
111+
112+
We've used the `st-supabase-connection` library here in combination with `st.experimental_connection` to benefit from the ease of setting up the data connection, managing your credentials, and Streamlit's caching capabilities that native and community-built connections provide.
113+
114+
You can however still directly use the [Supabase Python Client Library](https://pypi.org/project/supabase/) library if you prefer, but you'll need to write more code to set up the connection and cache the results. See [Using the Supabase Python Client Library](/knowledge-base/tutorials/databases/supabase#using-the-supabase-python-client-library) below for an example.
115+
116+
</Tip>
117+
103118
## Write your Streamlit app
104119

105120
Copy the code below to your Streamlit app and run it.
@@ -108,36 +123,83 @@ Copy the code below to your Streamlit app and run it.
108123
# streamlit_app.py
109124

110125
import streamlit as st
111-
from supabase import create_client, Client
126+
from st_supabase_connection import SupabaseConnection
112127

113128
# Initialize connection.
114-
# Uses st.cache_resource to only run once.
115-
@st.cache_resource
116-
def init_connection():
117-
url = st.secrets["supabase_url"]
118-
key = st.secrets["supabase_key"]
119-
return create_client(url, key)
120-
121-
supabase = init_connection()
129+
conn = st.experimental_connection("supabase",type=SupabaseConnection)
122130

123131
# Perform query.
124-
# Uses st.cache_data to only rerun when the query changes or after 10 min.
125-
@st.cache_data(ttl=600)
126-
def run_query():
127-
return supabase.table("mytable").select("*").execute()
128-
129-
rows = run_query()
132+
rows = conn.query("*", table="mytable", ttl="10m").execute()
130133

131134
# Print results.
132135
for row in rows.data:
133136
st.write(f"{row['name']} has a :{row['pet']}:")
134137

135138
```
136139

137-
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).
140+
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="10m"` 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).
138141

139142
If everything worked out (and you used the example table we created above), your app should look like this:
140143

141144
![Finished app screenshot](/images/databases/supabase-10.png)
142145

143146
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.
147+
148+
## Using the Supabase Python Client Library
149+
150+
If you prefer to use the [Supabase Python Client Library](https://pypi.org/project/supabase/) directly, you can do so by following the steps below.
151+
152+
1. Add your Supabase Project URL and API key to your local app secrets:
153+
154+
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:
155+
156+
```toml
157+
# .streamlit/secrets.toml
158+
159+
SUPABASE_URL = "xxxx"
160+
SUPABASE_KEY = "xxxx"
161+
```
162+
163+
2. Add `supabase` to your requirements file:
164+
165+
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):
166+
167+
```bash
168+
# requirements.txt
169+
supabase==x.x.x
170+
```
171+
172+
3. Write your Streamlit app:
173+
174+
Copy the code below to your Streamlit app and run it.
175+
176+
```python
177+
# streamlit_app.py
178+
179+
import streamlit as st
180+
from supabase import create_client, Client
181+
182+
# Initialize connection.
183+
# Uses st.cache_resource to only run once.
184+
@st.cache_resource
185+
def init_connection():
186+
url = st.secrets["SUPABASE_URL"]
187+
key = st.secrets["SUPABASE_KEY"]
188+
return create_client(url, key)
189+
190+
supabase = init_connection()
191+
192+
# Perform query.
193+
# Uses st.cache_data to only rerun when the query changes or after 10 min.
194+
@st.cache_data(ttl=600)
195+
def run_query():
196+
return supabase.table("mytable").select("*").execute()
197+
198+
rows = run_query()
199+
200+
# Print results.
201+
for row in rows.data:
202+
st.write(f"{row['name']} has a :{row['pet']}:")
203+
```
204+
205+
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).

0 commit comments

Comments
 (0)