Spaces:
Running
Running
| """ | |
| Database helper — thin wrapper around Supabase client. | |
| Each thread gets its own client instance to avoid HTTP/2 connection sharing issues. | |
| """ | |
| import os | |
| import threading | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| from supabase import create_client, Client | |
| from supabase.client import ClientOptions | |
| load_dotenv(Path(__file__).parent.parent / ".env") | |
| SUPABASE_URL = os.environ.get("SUPABASE_URL", "").strip() | |
| SUPABASE_KEY = ( | |
| os.environ.get("SUPABASE_KEY", "").strip() | |
| or os.environ.get("SUPABASE_ANON_KEY", "").strip() | |
| ) | |
| SUPABASE_SERVICE_KEY = os.environ.get("SUPABASE_SERVICE_KEY", "").strip() | |
| _local = threading.local() | |
| _opts = ClientOptions(postgrest_client_timeout=30.0) | |
| def get_client() -> Client: | |
| """Returns a thread-local Supabase client (anon key).""" | |
| if not getattr(_local, "client", None): | |
| _local.client = create_client(SUPABASE_URL, SUPABASE_KEY, options=_opts) | |
| return _local.client | |
| def new_client() -> Client: | |
| return get_client() | |
| def get_service_client() -> Client: | |
| """Returns a thread-local Supabase client (service key).""" | |
| if not getattr(_local, "service_client", None): | |
| key = SUPABASE_SERVICE_KEY | |
| if not key: | |
| print("WARNING: SUPABASE_SERVICE_KEY is missing. Falling back to SUPABASE_KEY (anon). RLS might block operations.") | |
| key = SUPABASE_KEY | |
| _local.service_client = create_client(SUPABASE_URL, key, options=_opts) | |
| return _local.service_client | |
| def reset_service_client(): | |
| _local.service_client = None | |