Skip to main content

Streamlit Supabase Connection

Use Supabase Storage, Database, and Auth from Streamlit with Streamlit-aware caching and browser-session-safe authentication.

Open the interactive demo · Read the guides · View the changelog

Why use it?

  • Use st.connection() and Streamlit secrets for Supabase configuration.
  • Cache Storage and Database reads with familiar ttl values such as "10m".
  • Keep Supabase Auth tokens isolated to the current Streamlit browser session.
  • Upload st.file_uploader() results without first writing them to the app server.
  • Normalize Storage paths and infer common MIME types automatically.

Requirements

Component Supported version
Python 3.10 or newer
Streamlit 1.62.0 or newer
Supabase Python 2.22.0 or newer

Quickstart

Install the package:

pip install st-supabase-connection

Add your project URL and publishable key to .streamlit/secrets.toml:

[connections.supabase_connection]
SUPABASE_URL = "https://your-project.supabase.co"
SUPABASE_PUBLISHABLE_KEY = "sb_publishable_..."

Create the connection and make a cached read:

import streamlit as st

from st_supabase_connection import SupabaseConnection

connection = st.connection(
    "supabase_connection",
    type=SupabaseConnection,
)

buckets = connection.list_buckets(ttl="10m")
st.write(buckets)

The legacy SUPABASE_KEY setting is still supported. New user-facing apps should use a Supabase publishable key. Never use a secret or service_role key for user-scoped operations because those keys bypass Row Level Security.

You can also supply SUPABASE_URL and SUPABASE_PUBLISHABLE_KEY as environment variables, or pass url= and key= to st.connection().

Choose the right client

Streamlit connection objects are cached resources and may be shared between browser sessions. Choose the client based on whether the operation depends on a signed-in user.

Use case Recommended API
Public or anonymous cached reads The shared connection and its cached helpers
Supabase Auth connection.session_client().auth
Reads or writes protected by the signed-in user's RLS policies The same connection.session_client() used for sign-in
Privileged administrative work A separate, secured backend using a secret key—not a user-facing app flow

Create the session-scoped client inside the Streamlit script:

supabase = connection.session_client()

Reuse that client for Auth and user-specific operations. Do not put it in a module-level variable, st.cache_resource, or another global cache.

Caching behavior

There are two different kinds of ttl:

Where ttl is set What it controls
st.connection(..., ttl=...) How long Streamlit keeps the connection object
connection.list_buckets(ttl=...), connection.download(ttl=...), or execute_query(..., ttl=...) How long the returned result is cached

In most apps, omit ttl from st.connection() and set a finite ttl on reads that can change:

from st_supabase_connection import execute_query

countries = execute_query(
    connection.table("countries").select("id, name").order("name"),
    ttl="10m",
)
st.dataframe(countries.data)

Do not cache Auth calls. Starting in 2.2.1, execute_query() automatically bypasses caching for inserts, updates, upserts, deletes, and POST-based RPC calls. Direct .execute() calls also remain supported; ttl=0 fetches fresh data for reads.

See the caching guide for cache scope, user-specific queries, and invalidation considerations.

Common workflows

Upload from st.file_uploader

The uploaded file is handled in memory; it does not need to be copied to the app server first.

uploaded_file = st.file_uploader("Choose a file")

if uploaded_file is not None and st.button("Upload"):
    connection.upload(
        bucket_id="documents",
        source="local",
        file=uploaded_file,
        destination_path=f"uploads/{uploaded_file.name}",
        overwrite="false",
    )
    st.success("Upload complete")

Query the database

Use the shared connection for anonymous reads:

from st_supabase_connection import execute_query

response = execute_query(
    connection.table("countries").select("id, name").limit(20),
    ttl="5m",
)
st.dataframe(response.data)

Use the session client for rows protected by a signed-in user's RLS policies:

supabase = connection.session_client()
response = supabase.table("private_profiles").select("*").execute()
st.dataframe(response.data)

Sign in an existing user

supabase = connection.session_client()

email = st.text_input("Email")
password = st.text_input("Password", type="password")

if st.button("Sign in"):
    supabase.auth.sign_in_with_password(
        {"email": email, "password": password}
    )
    st.success("Signed in")

After sign-in, use the same supabase client for all operations that must carry the user's JWT.

Guides and recipes

Supported functionality

The connection includes Streamlit-friendly wrappers for commonly used Storage operations:

  • Bucket management: list_buckets(), get_bucket(), create_bucket(), update_bucket(), empty_bucket(), and delete_bucket()
  • Objects: upload(), download(), list_objects(), move(), and remove()
  • URLs: get_public_url(), create_signed_urls(), create_signed_upload_url(), and upload_to_signed_url()
  • Database: table() and the cached execute_query() helper
  • Auth and other user-scoped Supabase APIs: session_client()

Because session_client() returns the complete Supabase Python client, it can also be used for Functions, Realtime, and other SDK features that must carry the current user's session.

Upgrading

2.2.1

This patch fixes Storage cache isolation between projects and credentials, prevents execute_query() from caching writes, and returns independent copies of cached read responses. No public methods are removed and dependency minimums are unchanged.

get_public_url() now constructs URLs without caching; existing ttl arguments remain accepted but are ignored. Apps that manually clear cached results should use st.cache_data.clear(), not only st.cache_resource.clear().

From 2.1.x to 2.2.x

Version 2.2.0 requires Python 3.10+, Streamlit 1.62.0+, and Supabase Python 2.22.0+.

Apps using Auth should replace process-shared access:

# Deprecated
connection.auth.sign_in_with_password(credentials)

with a session-scoped client:

supabase = connection.session_client()
supabase.auth.sign_in_with_password(credentials)

connection.auth and cached_sign_in_with_password() remain available for compatibility but are deprecated. The latter no longer caches its result and ignores ttl.

See the 2.2.0 changelog for the complete migration notes.

Development

Install the project, then run the library and demo tests:

python -m pip install --editable .
python -m unittest discover --start-directory tests --verbose

The CI workflow tests Python 3.10–3.14 against the minimum and latest supported Streamlit releases.

For the reproducible demo runtime, use Python 3.12 and run from the repository root:

python -m pip install -r demo/requirements.txt
python -m pip check
python -m streamlit run demo/app.py

demo/requirements.txt pins the demo environment, including transitive dependencies; the published library keeps flexible dependency ranges. CI also tests this pinned set. Refresh the pins in a clean Python 3.12 environment when upgrading the demo, and run the suite plus the browser smoke checklist in RELEASING.md.

Black and isort use the repository's pyproject.toml settings.

Issues and pull requests are welcome in the GitHub repository.

Acknowledgements

This connector builds on Streamlit, Supabase Python, and the work of the Supabase open-source community.

If the project helps you, you can sponsor it on GitHub or buy me a coffee.

Release files for st-supabase-connection 2.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for st-supabase-connection 2.2.1
File Size Uploaded
st_supabase_connection-2.2.1.tar.gz 41.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for st-supabase-connection 2.2.1
File Interpreter ABI Platform
st_supabase_connection-2.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 54.0 kB

Release files / st_supabase_connection-2.2.1.tar.gz

Download URL st_supabase_connection-2.2.1.tar.gz
Size 41.5 kB
Tags Source
SHA-256 checksum
How to use checksums
65e1d0846e620ef6aa438ebd9f20d83d3e56403346d88337bb0a0f2b598605e4
BLAKE2b-256 checksum
How to use checksums
56e5943a8c17dd6f59e9fc46e68354b4b45b5145681c2adc2c8d5299172445c2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 6, 2026.

Transparency log

Release files / st_supabase_connection-2.2.1-py3-none-any.whl

Download URL st_supabase_connection-2.2.1-py3-none-any.whl
Size 12.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
44f6edbe1266187625221001f708079cdbc6be4304954f40942c89ecb1b68407
BLAKE2b-256 checksum
How to use checksums
9277253cb8c791e41305c2c6f3c0fe536b298dde52d13d31a0c586bbe638d6a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.2.1 This release

2 release files

2.2.0

2 release files

2.1.3

2 release files

2.1.2

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.0

2 release files

0.0.2

2 release files

0.0.1

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page