/supabase-py

Python Client for Supabase

Primary LanguagePythonMIT LicenseMIT

supabase-py

License: MIT CI Python Version Codecov Last commit GitHub commit activity Github Stars Github Forks Github Watchers GitHub contributors

Supabase client for Python. This mirrors the design of supabase-js

Status

  • Alpha: We are testing Supabase with a closed set of customers
  • Public Alpha: Anyone can sign up over at app.supabase.io. But go easy on us, there are a few kinks.
  • Public Beta: Stable enough for most non-enterprise use-cases
  • Public: Production-ready

We are currently in Public Alpha. Watch "releases" of this repo to get notified of major updates.

Watch this repo

Installation

Recommended: First, activate your virtual environment with your favourite environment management tool. For example, we like poetry and conda!

PyPi installation

Now install the package. (for > Python 3.7)

pip install supabase

Local installation

You can also installing from after cloning this repo. Install like below to install in Development Mode, which means when you edit the source code the changes will be reflected in your python module.

pip install -e .

Usage

It's usually best practice to set your API key environment variables in some way that isn't tracked by version control. For instance, don't put them in your python modules! Set the Key and URL for the supabase instance in the shell, or better yet, use a dotenv file. Here's how to set the variables in the shell.

export SUPABASE_URL="my-url-to-my-awesome-supabase-instance"
export SUPABASE_KEY="my-supa-dupa-secret-supabase-api-key"

We can then read the keys in the python source code.

import os
from supabase import SupabaseClient

url: str = os.environ.get("SUPABASE_URL")
key: str = os.environ.get("SUPABASE_KEY")

supabase: SupabaseClient = SupabaseClient(url, key)

Use the supabase client to interface with your database.

Running Tests

Currently, the test suites are in a state of flux. We are expanding our clients tests to ensure things are working, and for now can connect to this test instance, that is populated with the following table:

example of database table in Supabase Studio editor

The above test database is a blank supabase instance that has populated the countries table with the built in countries script that can be found in the supabase UI. You can launch the test scripts and point to the above test database by running

./test.sh

See issues for what to work on

Rough roadmap:

Client Library

This is a sample of how you'd use supabase-py. Functions and tests are WIP

Authenticate

import os
from supabase import SupabaseClient

url: str = os.environ.get("SUPABASE_TEST_URL")
key: str = os.environ.get("SUPABASE_TEST_KEY")

supabase: SupabaseClient = SupabaseClient(url, key)

# Create a random user login email and password.
random_email: str = "user@supamail.com"
random_password: str = "12345678"
user = supabase.auth.sign_up(email=random_email, password=random_password)

Sign-in

import os
from supabase import SupabaseClient


url: str = os.environ.get("SUPABASE_TEST_URL")
key: str = os.environ.get("SUPABASE_TEST_KEY")
supabase: SupabaseClient = SupabaseClient(url, key)

# Sign in using the user email and password.
random_email: str = "user@supamail.com"
random_password: str = "12345678"
user = supabase.auth.sign_in(email=random_email, password=random_password)

Managing Data

Insert Data

import os
from supabase import SupabaseClient


url: str = os.environ.get("SUPABASE_TEST_URL")
key: str = os.environ.get("SUPABASE_TEST_KEY")
supabase: SupabaseClient = SupabaseClient(url, key)

data = supabase.table("countries").insert({"name":"Germany"}).execute()

(NEW) Async Support

async def main():
    import os
    from supabase import AsyncSupabaseClient

    url: str = os.environ.get("SUPABASE_TEST_URL")
    key: str = os.environ.get("SUPABASE_TEST_KEY")

    async with AsyncSupabaseClient(url, key) as supabase:
        await supabase.table("countries").insert({"name":"Germany"}).execute()

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Select Data

import os
from supabase import SupabaseClient

url: str = os.environ.get("SUPABASE_TEST_URL")
key: str = os.environ.get("SUPABASE_TEST_KEY")

supabase: SupabaseClient = SupabaseClient(url, key)

data = supabase.table("countries").select("*").execute()

(NEW) Async Support

async def main():
    import os
    from supabase import AsyncSupabaseClient

    url: str = os.environ.get("SUPABASE_TEST_URL")
    key: str = os.environ.get("SUPABASE_TEST_KEY")

    async with AsyncSupabaseClient(url, key) as supabase:
        await supabase.table("countries").select("*").execute()

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Update Data

import os
from supabase import SupabaseClient

url: str = os.environ.get("SUPABASE_TEST_URL")
key: str = os.environ.get("SUPABASE_TEST_KEY")
supabase: SupabaseClient = SupabaseClient(url, key)

data = supabase.table("countries").update({"country": "Indonesia", "capital_city": "Jakarta"}).eq("id", 1).execute()

(NEW) Async Support

async def main():
    import os
    from supabase import AsyncSupabaseClient

    url: str = os.environ.get("SUPABASE_TEST_URL")
    key: str = os.environ.get("SUPABASE_TEST_KEY")

    async with AsyncSupabaseClient(url, key) as supabase:
        await supabase.table("countries").update({"country": "Indonesia", "capital_city": "Jakarta"}).eq("id", 1).execute()

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Delete Data

import os
from supabase import SupabaseClient

url: str = os.environ.get("SUPABASE_TEST_URL")
key: str = os.environ.get("SUPABASE_TEST_KEY")

supabase: SupabaseClient = SupabaseClient(url, key)
data = supabase.table("countries").delete().eq("id", 1).execute()

(NEW) Async Support

async def main():
    import os
    from supabase import AsyncSupabaseClient

    url: str = os.environ.get("SUPABASE_TEST_URL")
    key: str = os.environ.get("SUPABASE_TEST_KEY")

    async with AsyncSupabaseClient(url, key) as supabase:
        await supabase.table("countries").delete().eq("id", 1).execute()

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Realtime Changes

Realtime changes are unfortunately still a WIP. Feel free to file PRs to realtime-py

See Supabase Docs for full list of examples

Python and Supabase Resources