Code Monkey home page Code Monkey logo

supabase-community / supabase-py Goto Github PK

View Code? Open in Web Editor NEW
1.4K 34.0 166.0 1.46 MB

Python Client for Supabase. Query Postgres from Flask, Django, FastAPI. Python user authentication, security policies, edge functions, file storage, and realtime data streaming. Good first issue.

Home Page: https://supabase.com/docs/reference/python

License: MIT License

Python 94.66% PowerShell 0.45% Dockerfile 3.87% Makefile 1.02%
python community supabase auth authentication authorization data-science databases django fastapi

supabase-py's Introduction

supabase-py

Python client for Supabase

Set up a Local Development Environment

Clone the Repository

git clone https://github.com/supabase-community/supabase-py.git
cd supabase-py

Create and Activate a Virtual Environment

We recommend activating your virtual environment. For example, we like poetry and conda! Click here for more about Python virtual environments and working with conda and poetry.

Using venv (Python 3 built-in):

python3 -m venv env
source env/bin/activate  # On Windows, use .\env\Scripts\activate

Using conda:

conda create --name supabase-py
conda activate supabase-py

PyPi installation

Install the package (for > Python 3.7):

# with pip
pip install supabase

# with conda
conda install -c conda-forge supabase

Local installation

You can also install locally after cloning this repo. Install Development mode with pip install -e, which makes it so when you edit the source code the changes will be reflected in your python module.

Usage

Set your Supabase environment variables in a dotenv file, or using the shell:

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

Init client:

import os
from supabase import create_client, Client

url: str = os.environ.get("SUPABASE_URL")
key: str = os.environ.get("SUPABASE_KEY")
supabase: Client = create_client(url, key)

Use the supabase client to interface with your database.

Sign-up

user = supabase.auth.sign_up({ "email": users_email, "password": users_password })

Sign-in

user = supabase.auth.sign_in_with_password({ "email": users_email, "password": users_password })

Insert Data

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

# Assert we pulled real data.
assert len(data.data) > 0

Select Data

data = supabase.table("countries").select("*").eq("country", "IL").execute()

# Assert we pulled real data.
assert len(data.data) > 0

Update Data

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

Update data with duplicate keys

country = {
  "country": "United Kingdom",
  "capital_city": "London" # this was missing when it was added
}

data = supabase.table("countries").upsert(country).execute()
assert len(data.data) > 0

Delete Data

data = supabase.table("countries").delete().eq("id", 1).execute()

Call Edge Functions

def test_func():
  try:
    resp = supabase.functions.invoke("hello-world", invoke_options={'body':{}})
    return resp
  except (FunctionsRelayError, FunctionsHttpError) as exception:
    err = exception.to_dict()
    print(err.get("message"))

Download a file from Storage

bucket_name: str = "photos"

data = supabase.storage.from_(bucket_name).download("photo1.png")

Upload a file

bucket_name: str = "photos"
new_file = getUserFile()

data = supabase.storage.from_(bucket_name).upload("/user1/profile.png", new_file)

Remove a file

bucket_name: str = "photos"

data = supabase.storage.from_(bucket_name).remove(["old_photo.png", "image5.jpg"])

List all files

bucket_name: str = "charts"

data = supabase.storage.from_(bucket_name).list()

Move and rename files

bucket_name: str = "charts"
old_file_path: str = "generic/graph1.png"
new_file_path: str = "important/revenue.png"

data = supabase.storage.from_(bucket_name).move(old_file_path, new_file_path)

Roadmap

  • Wrap Postgrest-py
    • Add remaining filters
    • Add support for EXPLAIN
    • Add proper error handling
  • Wrap Realtime-py
    • Integrate with Supabase-py
    • Support WALRUS
    • Support broadcast (to check if already supported)
  • Wrap auth-py
    • Remove references to GoTrue-js v1 and do a proper release
    • Test and document common flows (e.g. sign in with OAuth, sign in with OTP)
    • Add MFA methods and SSO methods
    • Add Proof Key for Code Exchange (PKCE) methods. Unlike the JS library, we do not currently plan to support Magic Link (PKCE). Please use the token hash in tandem with verifyOTP instead.
  • Wrap storage-py
    • Support resumable uploads
    • Setup testing environment
    • Document how to properly upload different file types (e.g. jpeg/png and download it)
  • Wrap functions-py

Overall Tasks

  • Add async support across the entire library
  • Add FastAPI helper library (external to supabase-py)
  • Add django-supabase-postgrest (external to supabase-py)

Contributing

Contributing to the Python libraries are a great way to get involved with the Supabase community. Reach out to us on Discord or on our Github Discussions page if you want to get involved.

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:

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

Badges

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

supabase-py's People

Contributors

actions-user avatar anand2312 avatar awalias avatar cadnce avatar cloudguruab avatar dependabot[bot] avatar dreinon avatar fedden avatar j0 avatar joeriddles avatar julianolf avatar jv-aquino avatar leynier avatar lqmanh avatar mansueli avatar mohnish7 avatar morioki avatar mrpbennett avatar olirice avatar pheeef avatar prettyirrelevant avatar ramirond avatar rawandahmad698 avatar sampoder avatar sergiob-dev avatar shantanunair avatar silentworks avatar taloglu avatar tzvc avatar wellsilver avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

supabase-py's Issues

The "contains" query filter passes verbatim string "values" to Supabase in place of actual values.

Describe the bug
The "contains" filter appears to incorrectly pass the verbatim string "values" to Supabase, in place of the intended query values.

To Reproduce
Steps to reproduce the behavior:

  1. Create a Supabase client connected to a schema with table "table_name" having the JSONB column "column_name".
  2. Invoke the "contains" filter with supabase.table('table_name').select('*').cs('column_name','["value_name"]').execute()
  3. See the error: {'data': {'message': 'invalid input syntax for type json', 'code': '22P02', 'hint': None, 'details': 'Token "values" is invalid.'}, 'status_code': 400}

Expected behavior
This should return any rows from "table_name" where the JSONB entry in "column_name" contains the value "value_name".

'Error in $: not enough input' on .update()

Bug report

To Reproduce

res = db.table(table_name).update({"notes": notes}).eq("id", user_id).execute()

Expected behavior

Update and return me the row.

Actual behaviour

{'data': {'message': 'Error in $: not enough input'}, 'status_code': 400}

System information

  • Version of supabase-py: 0.0.2

Inconsistent results when using `eq`

Bug report

Describe the bug

I have a query that runs just as expected.

> supabase.table("storage").select('*').ilike('message', 'dude').execute()
{'data': [{'id': 2,
   'inserted_at': '2021-07-27T18:34:27.084558+00:00',
   'updated_at': '2021-07-27T18:34:27.084558+00:00',
   'email': '[email protected]',
   'message': 'dude'},
  {'id': 3,
   'inserted_at': '2021-07-27T18:34:31.482083+00:00',
   'updated_at': '2021-07-27T18:34:31.482083+00:00',
   'email': '[email protected]',
   'message': 'dude'}],
 'status_code': 200}

But notice what happens when I run:

> supabase.table("storage").select('*').like('email', '[email protected]').execute()
{'data': [], 'status_code': 200}

Somehow I cannot query the email like I can the other columns in my table. Is email a protected value?

I am using supabase-py version 0.0.2.

incorrect output from eq when characters certain characters used as input

related issue

Describe the bug

When you try to select rows where col1 = a.b it will look for "a.b" in the table (with quotes) and not a.b (without quotes) when you are using the eq function.

I have the table test

[{'id': 1, 'col1': 'a.b', 'col2': 'apple'}, 
{'id': 2, 'col1': '"a.b"', 'col2': 'banana'}, 
{'id': 3, 'col1': 'a,c', 'col2': 'mango'}, 
{'id': 4, 'col1': '"a,c"', 'col2': 'melon'}, 
{'id': 5, 'col1': 'aa', 'col2': 'cherry'}, 
{'id': 6, 'col1': '"aa"', 'col2': 'grape'}]

the command

x = supabase.table("test").select("*").eq("col1","a.b").execute()
print(x)

will get you
{'data': [{'id': 2, 'col1': '"a.b"', 'col2': 'banana'}], 'status_code': 200}

which is incorrect. You should get
{'data': [{'id': 1, 'col1': 'a.b', 'col2': 'apple'}], 'status_code': 200}

The same thing happens when you try with a,c. However aa works exactly as intended.

x = supabase.table("test").select("*").eq("col1","aa").execute()
print(x)

{'data': [{'id': 5, 'col1': 'aa', 'col2': 'cherry'}], 'status_code': 200}

This seems like an issue with sanitizing the input.

s
request_builder.py
s2
utils.py

The desired result can seemingly be achieved by bypassing eq and not using sanitizing_param.

x = supabase.table("test").select("*").filter("col1","eq","a.b").execute()
print(x)

{'data': [{'id': 1, 'col1': 'a.b', 'col2': 'apple'}], 'status_code': 200}

I am using supabase-py version 0.0.3.

"Realtime Changes" doesn't work with 'on'

Bug report

Describe the bug

The "Realtime Changes" snippet on the README doesn't work. It throws an error with "AttributeError: 'RequestBuilder' object has no attribute 'on'"

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Go to any editor.
  2. Type the code
 import os
 from supabase_py import create_client, Client
 
 url: str = os.environ.get("SUPABASE_URL")
 key: str = os.environ.get("SUPABASE_KEY")
 supabase: Client = create_client(url, key)
 subscription = supabase.table('countries').on('*',  lambda x: print(x)).subscribe()
  1. Run from terminal using python3 <script name>.py
  2. See error

Expected behavior

The snippet was expected to make a realtime change in the database, but it doesn't work because of this error

Traceback (most recent call last):
  File "/home/swapnanil/supabase-python-testing/script.py", line 7, in <module>
    subscription = supabase.table('countries').on('*',  lambda x: print(x)).subscribe()
AttributeError: 'RequestBuilder' object has no attribute 'on'

Screenshots

image

System information

  • OS: Ubuntu
  • Version of supabase-py [0.0.2]
  • Version of Python3 [3.8.10]

Which version is most up-to-date?

Describe the bug
pip by default install now version 0.1.2. But newest version is 0.0.3.

https://pypi.org/project/supabase/#history

image

To Reproduce
Steps to reproduce the behavior:

  1. pip install supabase

Expected behavior
It should install latest version

Screenshots
Above

Desktop (please complete the following information):
n/a
Smartphone (please complete the following information):
n/a
Additional context
n/a

unicode issues

When I follow the example to retrieve data I'm greeted with the following stacktrace:

In [4]: supabase.table("countries").select("*").execute()
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-4-91499f52c962> in <module>
----> 1 supabase.table("countries").select("*").execute()

/usr/lib/python3.8/site-packages/supabase_py/client.py in table(self, table_name)
     72         Alternatively you can use the `._from()` method.
     73         """
---> 74         return self.from_(table_name)
     75 
     76     def from_(self, table_name: str) -> SupabaseQueryBuilder:

/usr/lib/python3.8/site-packages/supabase_py/client.py in from_(self, table_name)
     79         See the `table` method.
     80         """
---> 81         query_builder = SupabaseQueryBuilder(
     82             url=f"{self.rest_url}/{table_name}",
     83             headers=self._get_auth_headers(),

/usr/lib/python3.8/site-packages/supabase_py/lib/query_builder.py in __init__(self, url, headers, schema, realtime, table)
     71             **headers,
     72         }
---> 73         self.session = AsyncClient(base_url=url, headers=headers)
     74         # self._subscription = SupabaseRealtimeClient(realtime, schema, table)
     75         # self._realtime = realtime

/usr/lib/python3.8/site-packages/httpx/_client.py in __init__(self, auth, params, headers, cookies, verify, cert, http2, proxies, timeout, limits, pool_limits, max_redirects, event_hooks, base_url, transport, app, trust_env)
   1209         trust_env: bool = True,
   1210     ):
-> 1211         super().__init__(
   1212             auth=auth,
   1213             params=params,

/usr/lib/python3.8/site-packages/httpx/_client.py in __init__(self, auth, params, headers, cookies, timeout, max_redirects, event_hooks, base_url, trust_env)
     98         self._auth = self._build_auth(auth)
     99         self._params = QueryParams(params)
--> 100         self.headers = Headers(headers)
    101         self._cookies = Cookies(cookies)
    102         self._timeout = Timeout(timeout)

/usr/lib/python3.8/site-packages/httpx/_models.py in __init__(self, headers, encoding)
    549             self._list = list(headers._list)
    550         elif isinstance(headers, dict):
--> 551             self._list = [
    552                 (
    553                     normalize_header_key(k, lower=False, encoding=encoding),

/usr/lib/python3.8/site-packages/httpx/_models.py in <listcomp>(.0)
    553                     normalize_header_key(k, lower=False, encoding=encoding),
    554                     normalize_header_key(k, lower=True, encoding=encoding),
--> 555                     normalize_header_value(v, encoding),
    556                 )
    557                 for k, v in headers.items()

/usr/lib/python3.8/site-packages/httpx/_utils.py in normalize_header_value(value, encoding)
     54     if isinstance(value, bytes):
     55         return value
---> 56     return value.encode(encoding or "ascii")
     57 
     58 

UnicodeEncodeError: 'ascii' codec can't encode character '\u2026' in position 50: ordinal not in range(128)

In [5]: data = supabase.table("countries").select("*").execute()
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
<ipython-input-5-a2ce57b52ae2> in <module>
----> 1 data = supabase.table("countries").select("*").execute()

/usr/lib/python3.8/site-packages/supabase_py/client.py in table(self, table_name)
     72         Alternatively you can use the `._from()` method.
     73         """
---> 74         return self.from_(table_name)
     75 
     76     def from_(self, table_name: str) -> SupabaseQueryBuilder:

/usr/lib/python3.8/site-packages/supabase_py/client.py in from_(self, table_name)
     79         See the `table` method.
     80         """
---> 81         query_builder = SupabaseQueryBuilder(
     82             url=f"{self.rest_url}/{table_name}",
     83             headers=self._get_auth_headers(),

/usr/lib/python3.8/site-packages/supabase_py/lib/query_builder.py in __init__(self, url, headers, schema, realtime, table)
     71             **headers,
     72         }
---> 73         self.session = AsyncClient(base_url=url, headers=headers)
     74         # self._subscription = SupabaseRealtimeClient(realtime, schema, table)
     75         # self._realtime = realtime

/usr/lib/python3.8/site-packages/httpx/_client.py in __init__(self, auth, params, headers, cookies, verify, cert, http2, proxies, timeout, limits, pool_limits, max_redirects, event_hooks, base_url, transport, app, trust_env)
   1209         trust_env: bool = True,
   1210     ):
-> 1211         super().__init__(
   1212             auth=auth,
   1213             params=params,

/usr/lib/python3.8/site-packages/httpx/_client.py in __init__(self, auth, params, headers, cookies, timeout, max_redirects, event_hooks, base_url, trust_env)
     98         self._auth = self._build_auth(auth)
     99         self._params = QueryParams(params)
--> 100         self.headers = Headers(headers)
    101         self._cookies = Cookies(cookies)
    102         self._timeout = Timeout(timeout)

/usr/lib/python3.8/site-packages/httpx/_models.py in __init__(self, headers, encoding)
    549             self._list = list(headers._list)
    550         elif isinstance(headers, dict):
--> 551             self._list = [
    552                 (
    553                     normalize_header_key(k, lower=False, encoding=encoding),

/usr/lib/python3.8/site-packages/httpx/_models.py in <listcomp>(.0)
    553                     normalize_header_key(k, lower=False, encoding=encoding),
    554                     normalize_header_key(k, lower=True, encoding=encoding),
--> 555                     normalize_header_value(v, encoding),
    556                 )
    557                 for k, v in headers.items()

/usr/lib/python3.8/site-packages/httpx/_utils.py in normalize_header_value(value, encoding)
     54     if isinstance(value, bytes):
     55         return value
---> 56     return value.encode(encoding or "ascii")
     57 
     58 

UnicodeEncodeError: 'ascii' codec can't encode character '\u2026' in position 50: ordinal not in range(128)

I've tried this on Python 3.7, 3.8, and 3.9 all with similar results. I've also tried different OSes (OSX, Linux), but both fail in similar fashion.

Can't upload anything to bucket

I read the doc and after connected, I can't upload anything in the storage bucket.

url=  "XXXXX"
key = "XXXXXXXXX
supabase: Client = create_client(url, key)
my_file = os.path.dirname(os.path.abspath("__file__")) + "/file.jpg"
storage.upload(path=supabase.storage_url, file=my_file)

It doesn't work and don't print any error.

Row Level Security and Python

Hi Folks!

I am calling a python API from Vue app where an user is logged in using supabase. This Python API was created using FastAPI and I have shared the same JWT secret and algorithm so I can ensure who is calling the API. The problem is when I try to execute an insert using supabase client + anon key I am receiving a RLS error, seems that it can't identify who is calling the insert from the python client.

My RLS is:

Enable insert for authenticated users only
(role() = 'authenticated'::text)

Is it possible somehow to pass which user is calling the python API using supabase-py? I do have the access_token sent by the javascript client but I have no idea how to share it and use on supabase.table("projects").insert

Uploaded images are always 1.37 MB big and can't be opened

supabase.storage().StorageFileAPI(id_='watermarked').upload(f'{_id}/{username}-{imageid}', os.path.dirname(os.path.abspath("__file__")) + "/embedded.jpg", {'Content-type':"image/jpg"})

The file I'm trying to upload has a size of ~530KB.
But on supabase it shows 1.37MB and can't be opened.

Postgrest errors do not get caught, returns false positives

Bug report

Describe the bug

Example error that gets returned in 'data' instead of in 'error' in response from an .insert operation

{'data': {'hint': None, 'details': 'Failing row contains (null, 4, open-chat, 2021-07-12 16:04:41.982201+00).', 'code': '23502', 'message': 'null value in column "id" violates not-null constraint'}, 'status_code': 400}

To Reproduce

You can easily reproduce this with most errors like not-null constraints, missing columns.

In this case, all I did was try to insert a row with a null value in a not-null column

Expected behavior

error is not None

AttributeError: 'RequestBuilder' object has no attribute 'on'

Bug report

Describe the bug

The Python client doesn't support realtime subscription and fails with "AttributeError: 'RequestBuilder' object has no attribute 'on'".

(Update 17/01/22: This was an example originally forming part of the README)

To Reproduce

Using the following example from the original readme:

subscription = supabase.table("countries").on("*", lambda x: print(x)).subscribe()`

Expected behavior

For each postgres db change to be printed.

System information

  • MacOS 11.3 Beta
  • Version of supabase-js: [0.0.2]
  • Version of Node.js: [N/A - Using hosted]

Additional context

Add any other context about the problem here.

Supabase is recognizing API request but not completing insert action

Hi, I am trying to use the API to insert/manipulate data in supabase but while API requests are being recognized no action is being taken? Does anybody know why this would be? Any help appreciated
Code:

from supabase import create_client, Client

supabaseUrl = 'REDACTED'
supabaseKey = "auth/private_key.txt"
supabase = create_client(supabaseUrl, supabaseKey)
supabase.table('tutorial').insert({'Path-Name': 'Path1', 'Action': 'Forwrad', 'Distance': 4}).execute()

X-Client-Info header

we're rolling out a header similar to Stripe's App-Data in all of the client libs so issues can be debugged more easily between the client and the backend

the javascript libs are done already: supabase/supabase-js#238

the format is: X-Client-Info: supabase-js/1.11.0

for client libs that wrap others (like how supabase-js wraps gotrue-js) we allow the wrapper lib to overwrite the wrapped lib's header (given that we can infer the gotrue-js version based on which supabase-js was used to make the call)

any help with rolling this out here would be incredible

Security Issue: Supabase-Py pulls in a vulnerable version of websockets library

Supabase-Py's dependencies pull in a version of the websockets library vulnerable to GHSA-8ch4-58qp-g3mp

I don't know if Supabase-Py itself is actually vulnerable in any way, but this is a headache for anyone using Supabase-Py because we can't update our own version of the websockets library to a non-vulnerable version.

Here is example output from Poetry's dependency solver when attempting to use both Supabase and a non-vulnerable version of Websockets in the same application:

Using version ^10.0 for websockets

Updating dependencies
Resolving dependencies... (4.4s)

  SolverProblemError

  Because no versions of supabase-py match >0.0.2,<0.0.3
   and supabase-py (0.0.2) depends on realtime-py (>=0.1.2,<0.2.0), supabase-py (>=0.0.2,<0.0.3) requires realtime-py (>=0.1.2,<0.2.0).
  Because realtime-py (0.1.2) depends on websockets (>=8.1,<9.0)
   and no versions of realtime-py match >0.1.2,<0.2.0, realtime-py (>=0.1.2,<0.2.0) requires websockets (>=8.1,<9.0).
  Thus, supabase-py (>=0.0.2,<0.0.3) requires websockets (>=8.1,<9.0).
  So, because <your-app> depends on both supabase-py (^0.0.2) and websockets (^10.0), version solving failed.

Add support for synchronous RPC calls

RPC calls are asynchronous as _execute_monkey_patch doesn't effect them. This is annoying because all the other calls in supabase-py are synchronous.

invite_user_by_email doesn't work well

When i use invite_user_by_email like this:

import os
import time
from supabase_py import create_client, Client

url: str = os.environ.get("SUPABASE_URL")
key: str = os.environ.get("SUPABASE_KEY")
supabase: Client = create_client(url, key)
# Sign in using the user email and password.
random_email: str = "[email protected]"
random_password: str = "fqj13bnf2hiu23h"
user = supabase.auth.sign_in(email=random_email, password=random_password)
print(user)
res = supabase.auth.api.invite_user_by_email(email="[email protected]")
print(res)

it returns

{'access_token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjMxOTQ5NjAwLCJzdWIiOiJmNmQ2N2UwZS0wMGE0LTRmMTQtODMzNi02MzZhMDA4MTFlNzQiLCJlbWFpbCI6InRpYW53ZWlzdHlsZUBnbWFpbC5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIn0sInVzZXJfbWV0YWRhdGEiOnt9LCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9._Su3gKyoH4F1xqhpDoJ3jLstrna62bw0KlpgfXCxBao', 'token_type': 'bearer', 'expires_in': 3600, 'refresh_token': 'RGYuYWIgyXR-Un3CPM_lzw', 'user': {'id': 'f6d67e0e-00a4-4f14-8336-636a00811e74', 'aud': 'authenticated', 'role': 'authenticated', 'email': '[email protected]', 'email_confirmed_at': '2021-09-18T06:03:30.045114Z', 'phone': '', 'confirmed_at': '2021-09-18T06:03:30.045114Z', 'email_change_confirm_status': 0, 'last_sign_in_at': '2021-09-18T06:20:00.979290632Z', 'app_metadata': {'provider': 'email'}, 'user_metadata': {}, 'created_at': '2021-09-18T06:03:29.935682Z', 'updated_at': '2021-09-18T06:20:00.985069Z'}, 'status_code': 200}
{'code': 401, 'msg': 'User not allowed', 'status_code': 401}

Current upload does not support inclusion of mime-type

Our current upload/update methods do not include the mime-type. As such, when we upload photos to storage and download them again they don't render properly.

The current fix was proposed by John on the discord channel. We should integrate it in so that Users can download/use photos.

    multipart_data = MultipartEncoder(
        fields={
            "file": (
                "party-parrot.gif",
                open("./out/party-parrot.gif", 'rb'),
                "image/gif"
            )
        })

    formHeaders = {
        "Content-Type": multipart_data.content_type,
    }

    headers = dict(supabase._get_auth_headers(), **formHeaders)
    response = requests.post(
        url=request_url,
        headers=headers,
        data=multipart_data,
    )

Update Documentation

Improve documentation

Documentation as a whole is missing from the client library. It would be nice if we could furnish the [Sphinx Page] (https://supabase.readthedocs.io/en/develop/) with relevant documentation preferably from autodoc.

Currently this would mean documenting:

  • Auth
  • Storage
  • QueryBuilder

auth.signin without password always gives status code 200

Describe the bug
Given the following code:

@user_route.get("/signin/")
async def signin(email:str, password:Optional[str]=None):
    if password:
        user = supabase.auth.sign_in(email=email, password=password)
    else:
        user = supabase.auth.sign_in(email=email)
    return user

If the else statement gets triggered(Sign in without a password), it sends a magic link to the user which allows them to sign up (I like this feature). However, it then returns a status code of 200. In the given case, how would you tell apart sign-ups from sign-ins?

Expected behavior
Some sort of distinction between sign-in and sign-up in the case of passwordless sign-in

Additional context
Do educate me if this is not how I should look at it - It's my first time working with Supabase

Add `MAINTAINERS.md`

Is your feature request related to a problem? Please describe.
It is unclear to me who maintains this project and who is a required reviewer on pull requests.

Describe the solution you'd like
I would like a MAINTAINERS.md file at the root of the repository that lists the project maintainers. In either this file or in CONTRIBUTING.md, I would like additional information to understand the review process for PRs.

Examples of MAINTAINERS.md:

Describe alternatives you've considered

  • Adding this information to CONTRIBUTING.md instead.

Additional context
N/A

Tutorial request: Streamlit

There have been multiple requests for a streamlit tutorial. For this task, we're looking for a tutorial or blogpost which showcases the use of supabase with Streamlit.

There are no restrictions on the type of tutorial and any number of people can take this issue up. This issue is open for creative exploration but feel free to tag/ping me if ideas are needed.

Running .rpc() results in missing API key

Bug report

Describe the bug

Running the .rpc() method to call a stored procedure ends up with a response containing the following message:
No API key found in request

Using .table() with works fine.

Additional context

I'm not sure if this is a bug or if i miss a place passing the required api key but according to the documentation and looking into the code, there is no place where i should pass a key additionally to the supabase_key

Type Hints for Supabase-py

It would be nice if we could get type hints on the library so that we can allow users to sanity check their code.

Thank you @dreinon for proposing this!

Cannot create a bucket using the storage client

Describe the bug
The method from the storage client responsible for creating new buckets is not working properly, it just prints a generic HTTP error message.

To Reproduce
Steps to reproduce the behavior:

  1. Create a client instance.
  2. Retrieve the storage client.
  3. Execute the create_bucket method.
from supabase import create_client

url = "https://xxx.supabase.co"
key = "xxx"
client = create_client(url, key)
storage = client.storage()
storage.create_bucket("mybucket")

Expected behavior
The bucket is not created and the following message is printed out.

HTTP error occurred: 400 Client Error: Bad Request for url: https://xxx.supabase.co/storage/v1/bucket

Additional context
After debugging the request performed by the method I could see a more detailed error message.

The Supabase API was returning the following payload:

{
  "statusCode": "400",
  "error": "Bad Request",
  "message": "body should be object"
}

I fixed that by explicitly defining the content-type of the request as application/json. Then executed the method again and received another error.

{
  "statusCode": "400",
  "error": "Bad Request",
  "message": "body should have required property 'name'"
}

Following the link for the API documentation at the GitHub repo of Supabase storage middleware I could confirm that name and not id is the only required property in order to create a new bucket.

I changed the property name and finally manage to create the bucket. 🙂

Tutorial Request: FastAPI

There have been multiple requests for a FastAPI tutorial. For this task, we're looking for a tutorial or blogpost which showcases the use of supabase with FastAPI.

There are no restrictions on the type of tutorial and any number of people can take this issue up. This issue is open for creative exploration but feel free to tag/ping me if ideas are needed.

Select request aren't updating

Bug report

Describe the bug

Hey Team 👋

I am experiencing a strange issue where I am getting stale results when using the .select SQL function.

def does_signup_exist(phone_number: str) -> Union[bool, None]:
    query = f"* from signups where phone_number = '{phone_number}'"
    print(query)
    data = client.table("signups").select(query).execute()
    print(data)

I've changed the phone number several times but I still get back results despite certain phone numbers not existing. When I copy and paste the query into the interactive Supbase SQL console in the browser I get a different result than the client.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Query for a result, r1, using the syntax seen above
  2. Query for a different result, r2, using the syntax seen above
  3. Observe the results r1 == r2

Expected behavior

New result r2 should be updated based on the new query

Screenshots

If applicable, add screenshots to help explain your problem.

System information

  • OS: [e.g. macOS, Windows]
  • Browser (if applies) [e.g. chrome, safari]
  • Version of supabase-js: [e.g. 6.0.2]
  • Version of Node.js: [e.g. 10.10.0]

Additional context

Add any other context about the problem here.

Unable to Install

Bug report

Describe the bug

Syntax bug on install:

Traceback (most recent call last):
  File "/Users/wolf/test/supabase-py/test.py", line 2, in <module>
    from supabase_py import create_client, Client
  File "/Users/wolf/test/supabase-py/supabase_py/__init__.py", line 2, in <module>
    from . import lib
  File "/Users/wolf/test/supabase-py/supabase_py/lib/__init__.py", line 2, in <module>
    from . import query_builder
  File "/Users/wolf/test/supabase-py/supabase_py/lib/query_builder.py", line 8, in <module>
    from .realtime_client import SupabaseRealtimeClient
  File "/Users/wolf/test/supabase-py/supabase_py/lib/realtime_client.py", line 21
    if (payload.type === 'UPDATE' or payload.type === 'DELETE'):                  ^

To Reproduce

clone python3 -m venv env source env/bin/activate clone pip install -e . and run example code in README

import os
from supabase_py import create_client, Client

url: str = "URL"
key: str = "KEY"
supabase: Client = create_client(url, key)

Expected behavior

A successful import and set up of client

Screenshots

If applicable, add screenshots to help explain your problem.

System information

Additional context

These repo is awesome and would definitely streamline part of the application i'm building on Supabase - a python API would like to read from the database and perform some calcs - but I can't seem to stand it up. Tried all of the branches.

[ERROR] AttributeError: module 'typing' has no attribute '_ClassVar', supabase-py on AWS Lambda

AWS Lambda returns the error below when importing supabase-py.

The error appears on runtimes: python 3.7 and 3.8.

Possibly related to the typing module as one of its dependencies.

Issues with typing Python-3 & AWS Lambda

Bug report

[ERROR] AttributeError: module 'typing' has no attribute '_ClassVar'
Traceback (most recent call last):
  File "/var/task/serverless_sdk/__init__.py", line 144, in wrapped_handler
    return user_handler(event, context)
  File "/var/task/s_task.py", line 25, in error_handler
    raise e
  File "/var/task/s_task.py", line 20, in <module>
    user_handler = serverless_sdk.get_user_handler('index.handler')
  File "/var/task/serverless_sdk/__init__.py", line 56, in get_user_handler
    user_module = import_module(user_module_name)
  File "/var/lang/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/var/task/index.py", line 8, in <module>
    from supabase_py import Client, create_client
  File "/var/task/supabase_py/__init__.py", line 2, in <module>
    from . import lib
  File "/var/task/supabase_py/lib/__init__.py", line 2, in <module>
    from . import query_builder
  File "/var/task/supabase_py/lib/query_builder.py", line 8, in <module>
    from .realtime_client import SupabaseRealtimeClient
  File "/var/task/supabase_py/lib/realtime_client.py", line 3, in <module>
    from realtime_py.connection import Socket
  File "/var/task/realtime_py/__init__.py", line 2, in <module>
    from realtime_py.connection import Socket
  File "/var/task/realtime_py/connection.py", line 11, in <module>
    from realtime_py.message import HEARTBEAT_PAYLOAD, PHOENIX_CHANNEL, ChannelEvents, Message
  File "/var/task/realtime_py/message.py", line 5, in <module>
    @dataclass
  File "/var/task/dataclasses.py", line 958, in dataclass
    return wrap(_cls)
  File "/var/task/dataclasses.py", line 950, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
  File "/var/task/dataclasses.py", line 801, in _process_class
    for name, type in cls_annotations.items()]
  File "/var/task/dataclasses.py", line 801, in <listcomp>
    for name, type in cls_annotations.items()]
  File "/var/task/dataclasses.py", line 659, in _get_field
    if (_is_classvar(a_type, typing)
  File "/var/task/dataclasses.py", line 550, in _is_classvar
    return type(a_type) is typing._ClassVar

Add support for upsert

Is your feature request related to a problem? Please describe.
A lot of the time I need to either insert data or update existing data (depending on if it's created or not).

Describe the solution you'd like
Add upsert functionality.

Describe alternatives you've considered
A query followed by an insert or update.

data = supabase.table('table').select(*).eq('id', 'something').execute()
if len(data.get('id', [])) > 0:
  // update the data
else:
  // insert the data

Additional context
Taken from the supabase docs, I couldn't find this functionality in this library. Does something to this effect exist yet?

const { data, error } = await supabase
  .from('messages')
  .upsert({ id: 3, message: 'foo', username: 'supabot' })

Delete from database, fails in response

Describe the bug
In query_builder.py at line 33 in return, response.json() fails with JSONDecodeError when api returns response.content as empty.

To Reproduce
Steps to reproduce the behavior:
Delete object from supabase database:

client.delete().eq("some id", some_id).execute()

Object is successfully deleted, but response message is not able to convert to json at throws exception.

Expected behavior
Deletion of object, and a response message telling me it was successfully, or an empty one.

Desktop (please complete the following information):

  • OS: macOS Monterey
  • Browser: Google Chrome
  • Version 96.0.4664.45 (Official Build) (arm64)

Please provide more info on return types from execute

The return types from execute currently require trial and error to unpack. Would it be possible to add more information in the README.md explaining what the potential return types are and what they mean?

e.g. the returned value seems to have changed from a prior version of postgrest-py: it now returns a tuple of data and a None value. But it isn't clear what this None value represents and how to handle potential response errors on the return types?

README

Improve documentation

This is just a general note to say that the documentation in the README.md file is out of date - we should probably take a little bit of time just to clean/polish it up given it's the first point of reference that the users will likely get to the project

BUG | default schema not being applied in CI

Describe the bug
I am attempting to query a table in DB and getting an error in GitHub Actions that I am not getting running locally.

Query being attempted:

supabase.table('meeting_types').select('*').execute()

I get the error:

requests.exceptions.MissingSchema: Invalid URL '***/rest/v1/meeting_types?select=%2A': No schema supplied. Perhaps you meant http://***/rest/v1/meeting_types?select=%2A

Screen shot of error stack trace:
Screen Shot 2021-12-26 at 4 10 41 PM

I'm doing lots of querying and inserting locally with no issues. First time trying to replicate in CI and am getting this error. I'm using v0.0.3 of the supabase package and like I said I've been successfully running this locally and have replicated that setup in CI.

Let me know of any additional context you may need 👍 thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.