Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 48 additions & 51 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ classifiers = [
python = "^3.7"
postgrest-py = "^0.6.0"
realtime = "^0.0.3"
gotrue = "^0.2.0"
gotrue = "^0.3.0"
httpx = ">=0.19,<0.22"

[tool.poetry.dev-dependencies]
Expand All @@ -32,7 +32,7 @@ commitizen = "^2.20.3"

[tool.commitizen]
name = "cz_conventional_commits"
version = "0.0.3"
version = "0.1.0"
version_files = [
"supabase/__init__.py",
"pyproject.toml:version"
Expand Down
22 changes: 11 additions & 11 deletions supabase/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from supabase.lib.auth_client import SupabaseAuthClient
from supabase.lib.client_options import ClientOptions
from supabase.lib.constants import DEFAULT_OPTIONS
from supabase.lib.realtime_client import SupabaseRealtimeClient
from supabase.lib.storage_client import SupabaseStorageClient

Expand All @@ -17,7 +16,7 @@ def __init__(
self,
supabase_url: str,
supabase_key: str,
**options,
options: ClientOptions = ClientOptions(),
):
"""Instantiate the client.

Expand All @@ -38,20 +37,18 @@ def __init__(
raise Exception("supabase_key is required")
self.supabase_url = supabase_url
self.supabase_key = supabase_key

settings = DEFAULT_OPTIONS.replace(**options)
settings.headers.update(self._get_auth_headers())
options.headers.update(self._get_auth_headers())
self.rest_url: str = f"{supabase_url}/rest/v1"
self.realtime_url: str = f"{supabase_url}/realtime/v1".replace("http", "ws")
self.auth_url: str = f"{supabase_url}/auth/v1"
self.storage_url = f"{supabase_url}/storage/v1"
self.schema: str = settings.schema
self.schema: str = options.schema

# Instantiate clients.
self.auth = self._init_supabase_auth_client(
auth_url=self.auth_url,
supabase_key=self.supabase_key,
client_options=settings,
client_options=options,
)
# TODO(fedden): Bring up to parity with JS client.
# self.realtime: SupabaseRealtimeClient = self._init_realtime_client(
Expand All @@ -62,7 +59,7 @@ def __init__(
self.postgrest = self._init_postgrest_client(
rest_url=self.rest_url,
supabase_key=self.supabase_key,
headers=settings.headers,
headers=options.headers,
)

def storage(self) -> SupabaseStorageClient:
Expand Down Expand Up @@ -149,7 +146,6 @@ def _init_supabase_auth_client(
return SupabaseAuthClient(
url=auth_url,
auto_refresh_token=client_options.auto_refresh_token,
detect_session_in_url=client_options.detect_session_in_url,
persist_session=client_options.persist_session,
local_storage=client_options.local_storage,
headers=client_options.headers,
Expand All @@ -175,7 +171,11 @@ def _get_auth_headers(self) -> Dict[str, str]:
}


def create_client(supabase_url: str, supabase_key: str, **options) -> Client:
def create_client(
supabase_url: str,
supabase_key: str,
options: ClientOptions = ClientOptions(),
) -> Client:
"""Create client function to instantiate supabase client like JS runtime.

Parameters
Expand All @@ -202,4 +202,4 @@ def create_client(supabase_url: str, supabase_key: str, **options) -> Client:
-------
Client
"""
return Client(supabase_url=supabase_url, supabase_key=supabase_key, **options)
return Client(supabase_url=supabase_url, supabase_key=supabase_key, options=options)
31 changes: 22 additions & 9 deletions supabase/lib/auth_client.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
from typing import Any, Dict
from typing import Dict, Optional

import gotrue
from gotrue import (
CookieOptions,
SyncGoTrueAPI,
SyncGoTrueClient,
SyncMemoryStorage,
SyncSupportedStorage,
)
from gotrue.constants import COOKIE_OPTIONS


class SupabaseAuthClient(gotrue.Client):
class SupabaseAuthClient(SyncGoTrueClient):
"""SupabaseAuthClient"""

def __init__(
self,
*,
url: str,
detect_session_in_url: bool = False,
auto_refresh_token: bool = False,
persist_session: bool = False,
local_storage: Dict[str, Any] = {},
headers: Dict[str, str] = {},
auto_refresh_token: bool = True,
persist_session: bool = True,
local_storage: SyncSupportedStorage = SyncMemoryStorage(),
cookie_options: CookieOptions = CookieOptions.parse_obj(COOKIE_OPTIONS),
api: Optional[SyncGoTrueAPI] = None,
replace_default_headers: bool = False,
):
"""Instanciate SupabaseAuthClient instance."""
super().__init__(
SyncGoTrueClient.__init__(
self,
url=url,
headers=headers,
detect_session_in_url=detect_session_in_url,
auto_refresh_token=auto_refresh_token,
persist_session=persist_session,
local_storage=local_storage,
cookie_options=cookie_options,
api=api,
replace_default_headers=replace_default_headers,
)
36 changes: 18 additions & 18 deletions supabase/lib/client_options.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import copy
import dataclasses
from dataclasses import dataclass, field
from typing import Any, Callable, Dict, Optional

from gotrue import SyncMemoryStorage, SyncSupportedStorage

from supabase import __version__

DEFAULT_HEADERS = {"X-Client-Info": f"supabase-py/{__version__}"}


@dataclasses.dataclass
@dataclass
class ClientOptions:
schema: str = "public"
"""
The Postgres schema which your tables belong to.
Must be on the list of exposed schemas in Supabase. Defaults to 'public'.
"""

headers: Dict[str, str] = dataclasses.field(default_factory=DEFAULT_HEADERS.copy)
headers: Dict[str, str] = field(default_factory=DEFAULT_HEADERS.copy)
"""Optional headers for initializing the client."""

auto_refresh_token: bool = True
Expand All @@ -24,14 +25,11 @@ class ClientOptions:
persist_session: bool = True
"""Whether to persist a logged in session to storage."""

detect_session_in_url: bool = True
"""Detect a session from the URL. Used for OAuth login callbacks."""

local_storage: Dict[str, Any] = dataclasses.field(default_factory=lambda: {})
local_storage: SyncSupportedStorage = field(default_factory=SyncMemoryStorage)
"""A storage provider. Used to store the logged in session."""

"""Options passed to the realtime-py instance"""
realtime: Optional[Dict[str, Any]] = None
"""Options passed to the realtime-py instance"""

fetch: Optional[Callable] = None
"""A custom `fetch` implementation."""
Expand All @@ -42,17 +40,19 @@ def replace(
headers: Optional[Dict[str, str]] = None,
auto_refresh_token: Optional[bool] = None,
persist_session: Optional[bool] = None,
detect_session_in_url: Optional[bool] = None,
local_storage: Optional[Dict[str, Any]] = None,
local_storage: Optional[SyncSupportedStorage] = None,
realtime: Optional[Dict[str, Any]] = None,
fetch: Optional[Callable] = None,
) -> "ClientOptions":
"""Create a new SupabaseClientOptions with changes"""
changes = {
key: value
for key, value in locals().items()
if key != "self" and value is not None
}
client_options = dataclasses.replace(self, **changes)
client_options = copy.deepcopy(client_options)
client_options = ClientOptions()
client_options.schema = schema or self.schema
client_options.headers = headers or self.headers
client_options.auto_refresh_token = (
auto_refresh_token or self.auto_refresh_token
)
client_options.persist_session = persist_session or self.persist_session
client_options.local_storage = local_storage or self.local_storage
client_options.realtime = realtime or self.realtime
client_options.fetch = fetch or self.fetch
return client_options
3 changes: 0 additions & 3 deletions supabase/lib/constants.py

This file was deleted.

Loading