| """ |
| Supabase client singleton — single source of truth. |
| Replaces scattered supabase client creation across routers. |
| |
| Usage: |
| from app.core.db import get_supabase |
| client = await get_supabase() |
| result = await client.table("alerts").select("*").execute() |
| """ |
|
|
| from __future__ import annotations |
|
|
| import logging |
| import os |
| from typing import Any |
|
|
| logger = logging.getLogger(__name__) |
|
|
| _client: Any = None |
|
|
|
|
| async def get_supabase() -> Any: |
| """Get or create the async Supabase client.""" |
| global _client |
| if _client is not None: |
| return _client |
|
|
| url = os.getenv("SUPABASE_URL", "") |
| key = os.getenv("SUPABASE_SERVICE_KEY", "") or os.getenv("SUPABASE_KEY", "") |
|
|
| if not url or not key: |
| logger.warning("supabase_not_configured") |
| return None |
|
|
| try: |
| from supabase import create_client as _create_sync |
| _client = _create_sync(url, key) |
| logger.info("supabase_connected", url=url[:30]) |
| return _client |
| except ImportError: |
| logger.error("supabase_package_missing — pip install supabase") |
| return None |
| except Exception as e: |
| logger.error("supabase_init_failed", error=str(e)) |
| return None |
|
|
|
|
| def get_supabase_sync() -> Any: |
| """Synchronous Supabase client for scripts and non-async contexts.""" |
| url = os.getenv("SUPABASE_URL", "") |
| key = os.getenv("SUPABASE_SERVICE_KEY", "") or os.getenv("SUPABASE_KEY", "") |
|
|
| if not url or not key: |
| return None |
|
|
| try: |
| from supabase import create_client |
| return create_client(url, key) |
| except (ImportError, Exception): |
| return None |
|
|