78 lines
3.7 KiB
Python
78 lines
3.7 KiB
Python
import os
|
|
from typing import Dict, Optional, Any, TypedDict, List
|
|
from supabase import create_client, Client
|
|
from supabase.lib.client_options import SyncClientOptions
|
|
from supabase_auth import SyncMemoryStorage
|
|
from modules.logger_tool import initialise_logger
|
|
|
|
logger = initialise_logger(__name__, os.getenv("LOG_LEVEL"), os.getenv("LOG_PATH"), 'default', True)
|
|
|
|
class CreateBucketOptions(TypedDict, total=False):
|
|
"""Options for bucket creation, matching Supabase API requirements"""
|
|
public: bool
|
|
file_size_limit: int
|
|
allowed_mime_types: List[str]
|
|
name: str
|
|
|
|
def _create_base_client(url: str, key: str, options: Optional[Dict[str, Any]] = None, access_token: Optional[str] = None) -> Client:
|
|
"""Create a base Supabase client with given configuration."""
|
|
client_options = SyncClientOptions(
|
|
schema="public",
|
|
storage=SyncMemoryStorage(),
|
|
headers={
|
|
"apikey": key,
|
|
"Authorization": f"Bearer {access_token if access_token else key}"
|
|
}
|
|
)
|
|
return create_client(url, key, options=client_options)
|
|
|
|
class SupabaseServiceRoleClient:
|
|
"""Supabase client for making authenticated requests using the service role key"""
|
|
|
|
def __init__(self, url: Optional[str] = None, service_role_key: Optional[str] = None, access_token: Optional[str] = None):
|
|
"""Initialize the Supabase client with URL and service role key"""
|
|
self.url = url or os.environ.get("SUPABASE_URL", "http://kong:8000")
|
|
self.service_role_key = service_role_key or os.environ.get("SERVICE_ROLE_KEY")
|
|
|
|
if not self.url or not self.service_role_key:
|
|
raise ValueError("SUPABASE_URL and SERVICE_ROLE_KEY must be provided")
|
|
|
|
# Initialize Supabase client with service role key and optional access token
|
|
self.supabase = _create_base_client(self.url, self.service_role_key, access_token=access_token)
|
|
|
|
def create_bucket(self, id: str, options: Optional[CreateBucketOptions] = None) -> Dict[str, Any]:
|
|
"""Create a storage bucket with the given ID and options"""
|
|
if options is None:
|
|
options = CreateBucketOptions()
|
|
if 'name' not in options:
|
|
options['name'] = id # Use ID as default name if not provided
|
|
return self.supabase.storage.create_bucket(id, options=options)
|
|
|
|
@classmethod
|
|
def for_admin(cls, access_token: str) -> 'SupabaseServiceRoleClient':
|
|
"""Create a client instance for the super admin using their access token"""
|
|
return cls(access_token=access_token)
|
|
|
|
class SupabaseAnonClient:
|
|
"""Supabase client for making authenticated requests using the anon key"""
|
|
|
|
def __init__(self, url: Optional[str] = None, anon_key: Optional[str] = None, access_token: Optional[str] = None):
|
|
"""Initialize the Supabase client with URL and anon key"""
|
|
self.url = url or os.environ.get("SUPABASE_URL", "http://kong:8000")
|
|
self.anon_key = anon_key or os.environ.get("ANON_KEY")
|
|
|
|
if not self.url or not self.anon_key:
|
|
raise ValueError("SUPABASE_URL and ANON_KEY must be provided")
|
|
|
|
# Initialize Supabase client with anon key and optional access token
|
|
self.supabase = _create_base_client(self.url, self.anon_key, access_token=access_token)
|
|
|
|
def create_bucket(self, id: str, options: Optional[CreateBucketOptions] = None) -> Dict[str, Any]:
|
|
"""Create a storage bucket with the given ID and options"""
|
|
return self.supabase.storage.create_bucket(id, options=options)
|
|
|
|
@classmethod
|
|
def for_user(cls, access_token: str) -> 'SupabaseAnonClient':
|
|
"""Create a client instance for a specific user using their access token"""
|
|
return cls(access_token=access_token)
|