MCPcopy Index your code
hub / github.com/SiddhantSadangi/st_supabase_connection

github.com/SiddhantSadangi/st_supabase_connection @v2.1.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v2.1.3 ↗ · + Follow
33 symbols 107 edges 4 files 19 documented · 58% updated 8mo agov2.1.3 · 2025-11-02★ 140
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

:electric_plug: Streamlit Supabase Connector

Downloads PyPI version License: MIT Issues PRs Welcome

A Streamlit connection component to connect Streamlit to Supabase Storage, Database, and Auth.

Contents

🚀 Quickstart

  1. Install the connector and its dependencies.

    bash pip install st-supabase-connection

  2. Provide your Supabase credentials. In Streamlit Cloud, add them to secrets.toml:

    toml [connections.supabase_connection] url = "https://your-project.supabase.co" key = "service_role_or_anon_key"

    For local development you can use environment variables (SUPABASE_URL, SUPABASE_KEY) or pass the values directly during connection creation.

  3. Create the cached connection in your app.

    ```python import streamlit as st from st_supabase_connection import SupabaseConnection

    st_supabase = st.connection( name="supabase_connection", type=SupabaseConnection, ttl=None, # cache indefinitely; override when you need fresher data )

    Example: list buckets without re-authenticating on every rerun

    buckets = st_supabase.list_buckets() st.write(buckets) ```

:student: Interactive tutorial

<a href="https://st-supabase-connection.streamlit.app/">
    <img src="https://static.streamlit.io/badges/streamlit_badge_black_white.svg" alt="Open in Streamlit" style="height: 60px !important;width: 217px !important;">
</a>

Web capture_2-12-2023_124639_st-supabase-connection streamlit app

:thinking: Why use this?

  • [x] Cache functionality to cache returned results. Save time and money on your API requests
  • [x] Same method names as the Supabase Python API. Minimum relearning required
  • [x] Exposes more storage methods than currently supported by the Supabase Python API. For example, update(), create_signed_upload_url(), and upload_to_signed_url()
  • [x] Handles common Supabase quirks—leading slashes are normalised, MIME types inferred, and downloads streamed in memory—so you spend less time on glue code.
  • [x] Less keystrokes required when integrating with your Streamlit app.

Examples with and without the connector

Without connectorWith 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,
    )  # returns (name, mime_type, bytes)

    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

  1. Install st-supabase-connection
pip install st-supabase-connection
  1. Set the SUPABASE_URL and SUPABASE_KEY Streamlit secrets as described here.

[!NOTE]
For local development outside Streamlit, you can also set these as your environment variables (recommended), or pass these to the url and key args of st.connection().

:magic_wand: Usage

  1. Import
from st_supabase_connection import SupabaseConnection, execute_query
  1. Initialize
st_supabase_client = st.connection(
    name="YOUR_CONNECTION_NAME",
    type=SupabaseConnection,
    ttl=None,
)
  1. Use the connection to work with Storage, Database, and Auth in a cached, Streamlit-friendly way:

    ```python

    Storage

    file_name, mime, data = st_supabase.download("bucket", "path/to/report.csv", ttl=300)

    Database (leverages postgrest-py under the hood)

    from st_supabase_connection import execute_query users = execute_query( st_supabase.table("users").select("name, email").order("created_at", desc=True), ttl="15m", )

    Auth (cached helper)

    st_supabase.cached_sign_in_with_password({"email": email, "password": password}) ```

: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

  • execute_query() - Executes the passed query with caching enabled.
  • All methods supported by postgrest-py. Auth
    • cached_sign_in_with_password() - Cached version of sign_in_with_password() for faster sign-in.
    • 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
      >>> execute_query(st_supabase_client.table("countries").select("*"), ttl=0)
      APIResponse(
          data=[
              {"id": 1, "name": "Afghanistan"},
              {"id": 2, "name": "Albania"},
              {"id": 3, "name": "Algeria"},
          ],
          count=None,
      )
      
      #### Query with join
      >>> execute_query(
              st_supabase_client.table("users").select("name, teams(name)", count="exact"),
              ttl="1h",
          )
      
      APIResponse(
          data=[
              {"name": "Kiran", "teams": [{"name": "Green"}, {"name": "Blue"}]},
              {"name": "Evan", "teams": [{"name": "Blue"}]},
          ],
          count=2,
      )
      
      #### Filter through foreign ta

Core symbols most depended-on inside this repo

Shape

Method 21
Function 10
Class 2

Languages

Python100%

Modules by API surface

src/st_supabase_connection/__init__.py28 symbols
demo/app.py3 symbols
setup.py1 symbols
demo/utils.py1 symbols

For agents

$ claude mcp add st_supabase_connection \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page