A Streamlit connection component for Supabase.
Project description
:electric_plug: Streamlit Supabase Connector
A Streamlit connection component to connect Streamlit to Supabase Storage, Database, and Auth.
:student: Interactive tutorial
:thinking: Why use this?
- Cache functionality to cache returned results. Save time and money on your API requests
- Same method names as the Supabase Python API. Minimum relearning required
- Exposes more storage methods than currently supported by the Supabase Python API. For example,
update(),create_signed_upload_url(), andupload_to_signed_url() - Less keystrokes required when integrating with your Streamlit app.
Examples with and without the connector
| Without connector | With connector |
| Download file to local system from Supabase storage | |
import mimetypes
import streamlit as st
from supabase import create_client
supabase_client = create_client(
supabase_url="...", supabase_key="..."
)
bucket_id = st.text_input("Enter the bucket_id")
source_path = st.text_input("Enter source path")
file_name = source_path.split("/")[-1]
if st.button("Request download"):
with open(file_name, "wb+") as f:
response = supabase_client.storage.from_(
bucket_id
).download(source_path)
f.write(response)
mime = mimetypes.guess_type(file_name)[0]
data = open(file_name, "rb")
st.download_button(
"Download file", data=data,
file_name=file_name, mime=mime,
)
|
import streamlit as st
from st_supabase_connection import SupabaseConnection
st_supabase_client = st.connection(
name="supabase_connection", type=SupabaseConnection
)
bucket_id = st.text_input("Enter the bucket_id")
source_path = st.text_input("Enter source path")
if st.button("Request download"):
file_name, mime, data = st_supabase_client.download(
bucket_id, source_path,
)
st.download_button(
"Download file", data=data,
file_name=file_name, mime=mime,
)
|
| Upload file from local system to Supabase storage | |
import streamlit as st
from supabase import create_client
supabase_client = create_client(
supabase_key="...", supabase_url="..."
)
bucket_id = st.text_input("Enter the bucket_id")
uploaded_file = st.file_uploader("Choose a file")
destination_path = st.text_input("Enter destination path")
overwrite = "true" if st.checkbox("Overwrite?") else "false"
with open(uploaded_file.name, "wb") as f:
f.write(uploaded_file.getbuffer())
if st.button("Upload"):
with open(uploaded_file.name, "rb") as f:
supabase_client.storage.from_(bucket_id).upload(
path=destination_path,
file=f,
file_options={
"content-type": uploaded_file.type,
"x-upsert": overwrite,
},
)
|
import streamlit as st
from st_supabase_connection import SupabaseConnection
st_supabase_client = st.connection(
name="supabase_connection", type=SupabaseConnection
)
bucket_id = st.text_input("Enter the bucket_id")
uploaded_file = st.file_uploader("Choose a file"):
destination_path = st.text_input("Enter destination path")
overwrite = "true" if st.checkbox("Overwrite?") else "false"
if st.button("Upload"):
st_supabase_client.upload(
bucket_id, "local", uploaded_file,
destination_path, overwrite,
)
|
:hammer_and_wrench: Setup
- Install
st-supabase-connection
pip install st-supabase-connection
- Set the
SUPABASE_URLandSUPABASE_KEYStreamlit secrets as described here.
[!NOTE]
For local development outside Streamlit, you can also set these as your environment variables (recommended), or pass these to theurlandkeyargs ofst.connection().
:magic_wand: Usage
- Import
from st_supabase_connection import SupabaseConnection
- Initialize
st_supabase_client = st.connection(
name="YOUR_CONNECTION_NAME",
type=SupabaseConnection,
ttl=None,
url="YOUR_SUPABASE_URL", # not needed if provided as a streamlit secret
key="YOUR_SUPABASE_KEY", # not needed if provided as a streamlit secret
)
- Use in your app to query tables and files. Happy Streamlit-ing! :balloon:
:ok_hand: Supported methods
Storage
-
delete_bucket() -
empty_bucket() -
get_bucket() -
list_buckets() -
create_bucket() -
upload() -
download() -
update_bucket() -
move() -
list_objects() -
create_signed_urls() -
get_public_url() -
create_signed_upload_url() -
upload_to_signed_url()
Database
-
query()- Runs a cached SELECT query - All methods supported by postgrest-py.
Auth
-
All methods supported by Supabase's Python API .
:books: Examples
:package: Storage operations
List existing buckets
>>> st_supabase_client.list_buckets(ttl=None)
[
SyncBucket(
id="bucket1",
name="bucket1",
owner="",
public=False,
created_at=datetime.datetime(2023, 7, 31, 19, 56, 21, 518438, tzinfo=tzutc()),
updated_at=datetime.datetime(2023, 7, 31, 19, 56, 21, 518438, tzinfo=tzutc()),
file_size_limit=None,
allowed_mime_types=None,
),
SyncBucket(
id="bucket2",
name="bucket2",
owner="",
public=True,
created_at=datetime.datetime(2023, 7, 31, 19, 56, 28, 203536, tzinfo=tzutc()),
updated_at=datetime.datetime(2023, 7, 31, 19, 56, 28, 203536, tzinfo=tzutc()),
file_size_limit=100,
allowed_mime_types=["image/jpg", "image/png"],
),
]
Create a bucket
>>> st_supabase_client.create_bucket("new_bucket")
{'name': 'new_bucket'}
Get bucket details
>>> st_supabase_client.get_bucket("new_bucket")
SyncBucket(id='new_bucket', name='new_bucket', owner='', public=True, created_at=datetime.datetime(2023, 8, 2, 19, 41, 44, 810000, tzinfo=tzutc()), updated_at=datetime.datetime(2023, 8, 2, 19, 41, 44, 810000, tzinfo=tzutc()), file_size_limit=None, allowed_mime_types=None)
Update a bucket
>>> st_supabase_client.update_bucket(
"new_bucket",
file_size_limit=100,
allowed_mime_types=["image/jpg", "image/png"],
public=True,
)
{'message': 'Successfully updated'}
Move files in a bucket
>>> st_supabase_client.move("new_bucket", "test.png", "folder1/new_test.png")
{'message': 'Successfully moved'}
List objects in a bucket
>>> st_supabase_client.list_objects("new_bucket", path="folder1", ttl=0)
[
{
"name": "new_test.png",
"id": "e506920e-2834-440e-85f1-1d5476927582",
"updated_at": "2023-08-02T19:53:22.53986+00:00",
"created_at": "2023-08-02T19:52:20.404391+00:00",
"last_accessed_at": "2023-08-02T19:53:21.833+00:00",
"metadata": {
"eTag": '"814a0034f5549e957ee61360d87457e5"',
"size": 473831,
"mimetype": "image/png",
"cacheControl": "max-age=3600",
"lastModified": "2023-08-02T19:53:23.000Z",
"contentLength": 473831,
"httpStatusCode": 200,
},
}
]
Empty a bucket
>>> st_supabase_client.empty_bucket("new_bucket")
{'message': 'Successfully emptied'}
Delete a bucket
>>> st_supabase_client.delete_bucket("new_bucket")
{'message': 'Successfully deleted'}
:file_cabinet: Database operations
Simple query
>>> st_supabase_client.query("*", table="countries", ttl=0).execute()
APIResponse(
data=[
{"id": 1, "name": "Afghanistan"},
{"id": 2, "name": "Albania"},
{"id": 3, "name": "Algeria"},
],
count=None,
)
Query with join
>>> st_supabase_client.query("name, teams(name)", table="users", count="exact", ttl="1h").execute()
APIResponse(
data=[
{"name": "Kiran", "teams": [{"name": "Green"}, {"name": "Blue"}]},
{"name": "Evan", "teams": [{"name": "Blue"}]},
],
count=None,
)
Filter through foreign tables
>>> st_supabase_client.query("name, countries(*)", count="exact", table="cities", ttl=None).eq(
"countries.name", "Curaçao"
).execute()
APIResponse(
data=[
{
"name": "Kralendijk",
"countries": {
"id": 2,
"name": "Curaçao",
"iso2": "CW",
"iso3": "CUW",
"local_name": None,
"continent": None,
},
},
{"name": "Willemstad", "countries": None},
],
count=2,
)
Insert rows
>>> st_supabase_client.table("countries").insert(
[{"name": "Wakanda", "iso2": "WK"}, {"name": "Wadiya", "iso2": "WD"}], count="None"
).execute()
APIResponse(
data=[
{
"id": 250,
"name": "Wakanda",
"iso2": "WK",
"iso3": None,
"local_name": None,
"continent": None,
},
{
"id": 251,
"name": "Wadiya",
"iso2": "WD",
"iso3": None,
"local_name": None,
"continent": None,
},
],
count=None,
)
:lock: Auth operations
[!NOTE]
If the call is valid, all Supabase Auth methods return the same response structure:{ "user": { "id": "e1f550fd-9cd1-44e4-bbe4-c04e91cf5544", "app_metadata": { "provider": "email", "providers": [ "email" ] }, "user_metadata": { "attribution": "I made it :)", "fname": "Siddhant" }, "aud": "authenticated", "confirmation_sent_at": null, "recovery_sent_at": null, "email_change_sent_at": null, "new_email": null, "invited_at": null, "action_link": null, "email": "test.user@abc.com", "phone": "", "created_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 365359, tzinfo=datetime.timezone.utc)", "confirmed_at": null, "email_confirmed_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 373966, tzinfo=datetime.timezone.utc)", "phone_confirmed_at": null, "last_sign_in_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 377070, tzinfo=datetime.timezone.utc)", "role": "authenticated", "updated_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 381584, tzinfo=datetime.timezone.utc)", "identities": [ { "id": "e1f550fd-9cd1-44e4-bbe4-c04e91cf5544", "user_id": "e1f550fd-9cd1-44e4-bbe4-c04e91cf5544", "identity_data": { "email": "siddhant.sadangi@gmail.com", "sub": "e1f550fd-9cd1-44e4-bbe4-c04e91cf5544" }, "provider": "email", "created_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 370040, tzinfo=datetime.timezone.utc)", "last_sign_in_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 370002, tzinfo=datetime.timezone.utc)", "updated_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 370040, tzinfo=datetime.timezone.utc)" } ], "factors": null }, "session": { "provider_token": null, "provider_refresh_token": null, "access_token": "***", "refresh_token": "***", "expires_in": 3600, "expires_at": 1696800390, "token_type": "bearer", "user": { "id": "e1f550fd-9cd1-44e4-bbe4-c04e91cf5544", "app_metadata": { "provider": "email", "providers": [ "email" ] }, "user_metadata": { "attribution": "I made it :)", "fname": "Siddhant" }, "aud": "authenticated", "confirmation_sent_at": null, "recovery_sent_at": null, "email_change_sent_at": null, "new_email": null, "invited_at": null, "action_link": null, "email": "test.user@abc.com", "phone": "", "created_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 365359, tzinfo=datetime.timezone.utc)", "confirmed_at": null, "email_confirmed_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 373966, tzinfo=datetime.timezone.utc)", "phone_confirmed_at": null, "last_sign_in_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 377070, tzinfo=datetime.timezone.utc)", "role": "authenticated", "updated_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 381584, tzinfo=datetime.timezone.utc)", "identities": [ { "id": "e1f550fd-9cd1-44e4-bbe4-c04e91cf5544", "user_id": "e1f550fd-9cd1-44e4-bbe4-c04e91cf5544", "identity_data": { "email": "siddhant.sadangi@gmail.com", "sub": "e1f550fd-9cd1-44e4-bbe4-c04e91cf5544" }, "provider": "email", "created_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 370040, tzinfo=datetime.timezone.utc)", "last_sign_in_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 370002, tzinfo=datetime.timezone.utc)", "updated_at": "datetime.datetime(2023, 10, 8, 20, 26, 30, 370040, tzinfo=datetime.timezone.utc)" } ], "factors": null } } }
Create new user
>>> st_supabase_client.auth.sign_up(dict(email='test.user@abc.com', password='***', options=dict(data=dict(fname='Siddhant',attribution='I made it :)'))))
Sign in with password
>>> st_supabase_client.auth.sign_in_with_password(dict(email='test.user@abc.com', password='***'))
Retrieve session
>>> st_supabase.auth.get_session()
Retrieve user
>>> st_supabase.auth.get_user()
Sign out
>>> st_supabase.auth.sign_out()
[!NOTE]
Check the Supabase Python API reference for more examples.
:star: Explore all options in a demo app
:bow: Acknowledgements
This connector builds upon the awesome work done by the open-source community in general and the Supabase Community in particular. I cannot be more thankful to all the authors whose work I have used either directly or indirectly.
:hugs: Want to support my work?
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file st-supabase-connection-1.2.2.tar.gz.
File metadata
- Download URL: st-supabase-connection-1.2.2.tar.gz
- Upload date:
- Size: 15.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e6508f96cb7edba69b06b80d65086bedc4baeac989780405556ca4b32862053
|
|
| MD5 |
798f39bdd431280c257c4e1b2b0884e7
|
|
| BLAKE2b-256 |
6a7cbb6e5b7a521fbe264c0b22287adb0663747d5b4777fc285498ae27278673
|
File details
Details for the file st_supabase_connection-1.2.2-py3-none-any.whl.
File metadata
- Download URL: st_supabase_connection-1.2.2-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a2d3ea32f69c2160315d52b7c0017a213772cdccc357b1f4020db468d5e4324
|
|
| MD5 |
660d1e62ef84f7aeddb84c8c4f8a0f47
|
|
| BLAKE2b-256 |
874aa50896b02bf51c06ae8c42e76e1e90969fb02607e6a5acafa750749c456d
|