Soumik Bose
optimization 404
bd469c1
Raw
History Blame Contribute Delete
4.77 kB
from __future__ import annotations
import asyncio
import logging
from typing import Any, Dict, List, Optional
from supabase import create_client, Client
from app.config import get_settings
logger = logging.getLogger(__name__)
class SupabaseClient:
def __init__(self, url: str, service_key: str):
self._url = url
self._service_key = service_key
self._client: Optional[Client] = None
async def initialize(self):
self._client = await asyncio.to_thread(create_client, self._url, self._service_key)
logger.info("Supabase client initialized")
@property
def client(self) -> Client:
if self._client is None:
raise RuntimeError("Supabase client not initialized. Call initialize() first.")
return self._client
async def close(self):
self._client = None
set_supabase_client(None)
logger.info("Supabase client closed")
# --- Table operations ---
async def select(
self, table: str, columns: str = "*",
eq: Optional[tuple[str, Any]] = None,
order: Optional[tuple[str, bool]] = None,
limit: Optional[int] = None,
offset: Optional[int] = None,
) -> List[Dict[str, Any]]:
query = self.client.table(table).select(columns)
if eq:
query = query.eq(eq[0], eq[1])
if order:
query = query.order(order[0], desc=order[1])
if limit:
query = query.limit(limit)
if offset:
query = query.offset(offset)
result = await asyncio.to_thread(query.execute)
return result.data if result else []
async def select_in(
self, table: str, column: str, values: List[Any],
columns: str = "*",
) -> List[Dict[str, Any]]:
query = self.client.table(table).select(columns).in_(column, values)
result = await asyncio.to_thread(query.execute)
return result.data if result else []
async def insert(
self, table: str, data: Dict[str, Any],
returning: str = "representation",
) -> Optional[Dict[str, Any]]:
query = self.client.table(table).insert(data, returning=returning)
result = await asyncio.to_thread(query.execute)
if result and result.data:
return result.data[0]
return None
async def update(
self, table: str, column: str, value: Any,
data: Dict[str, Any],
) -> List[Dict[str, Any]]:
query = self.client.table(table).update(data).eq(column, value)
result = await asyncio.to_thread(query.execute)
return result.data if result else []
async def delete(
self, table: str, column: str, value: Any,
) -> List[Dict[str, Any]]:
query = self.client.table(table).delete().eq(column, value)
result = await asyncio.to_thread(query.execute)
return result.data if result else []
async def upsert(
self, table: str, data: Dict[str, Any],
on_conflict: str = "id",
) -> Optional[Dict[str, Any]]:
query = self.client.table(table).upsert(data, on_conflict=on_conflict)
result = await asyncio.to_thread(query.execute)
if result and result.data:
return result.data[0]
return None
async def find_one(
self, table: str, column: str, value: Any,
columns: str = "*",
) -> Optional[Dict[str, Any]]:
rows = await self.select(table, columns=columns, eq=(column, value), limit=1)
return rows[0] if rows else None
async def find_all(
self, table: str, column: str, value: Any,
columns: str = "*",
) -> List[Dict[str, Any]]:
return await self.select(table, columns=columns, eq=(column, value))
async def count(
self, table: str, column: str, value: Any,
) -> int:
query = self.client.table(table).select("*", count="exact").eq(column, value)
result = await asyncio.to_thread(query.execute)
return result.count if hasattr(result, "count") and result.count else 0
_client_instance: Optional[SupabaseClient] = None
def get_supabase_client() -> Optional[SupabaseClient]:
global _client_instance
return _client_instance
def set_supabase_client(client: SupabaseClient):
global _client_instance
_client_instance = client
async def create_supabase_client() -> SupabaseClient:
settings = get_settings()
url = settings.supabase_url
key = settings.supabase_service_role_key
if not url or not key:
logger.warning("Supabase not configured (SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY missing)")
return None
client = SupabaseClient(url, key)
await client.initialize()
set_supabase_client(client)
return client