| from typing import Any, Dict, List, Optional |
| from supabase.client import create_client, Client |
| from loguru import logger |
|
|
| from .utils import timing_decorator_sync |
| from .constants import VEHICLE_KEYWORD_TO_COLUMN |
|
|
| class SupabaseClient: |
| def __init__(self, url: str, key: str): |
| """ |
| Khởi tạo SupabaseClient với url và key. |
| Input: url (str), key (str) |
| Output: SupabaseClient instance. |
| """ |
| self.client: Client = create_client(url, key) |
|
|
| @timing_decorator_sync |
| def get_page_token(self, page_id: str): |
| """ |
| Lấy access token của Facebook page từ Supabase. |
| Input: page_id (str) |
| Output: access_token (str) hoặc None nếu không có. |
| """ |
| try: |
| response = self.client.table('PageToken').select('token').eq('id', page_id).execute() |
| if response.data and len(response.data) > 0: |
| return response.data[0]['token'] |
| return None |
| except Exception as e: |
| logger.error(f"Error getting page token: {e}") |
| return None |
|
|
| @timing_decorator_sync |
| def match_documents(self, embedding: List[float], match_count: int = 20, vehicle_keywords: Optional[List[str]] = None): |
| """ |
| Truy vấn vector similarity search qua RPC match_documents. |
| Input: embedding (list[float]), match_count (int), vehicle_keywords (list[str] hoặc None) |
| Output: list[dict] kết quả truy vấn. |
| """ |
| try: |
| payload = { |
| 'query_embedding': embedding, |
| 'match_threshold': 0.1, |
| 'match_count': match_count |
| } |
| if vehicle_keywords: |
| vehicle_columns = [VEHICLE_KEYWORD_TO_COLUMN[k] for k in vehicle_keywords if k in VEHICLE_KEYWORD_TO_COLUMN] |
| if vehicle_columns: |
| payload['vehicle_filters'] = vehicle_columns |
| response = self.client.rpc( |
| 'match_documents', |
| payload |
| ).execute() |
|
|
| if response.data: |
| return response.data |
| return [] |
| except Exception as e: |
| logger.error(f"Error matching documents: {e}") |
| return [] |
|
|
| @timing_decorator_sync |
| def store_embedding(self, text: str, embedding: List[float], metadata: Dict[str, Any]): |
| """ |
| Lưu embedding vào Supabase. |
| Input: text (str), embedding (list[float]), metadata (dict) |
| Output: bool (True nếu thành công, False nếu lỗi) |
| """ |
| try: |
| response = self.client.table('embeddings').insert({ |
| 'content': text, |
| 'embedding': embedding, |
| 'metadata': metadata |
| }).execute() |
| |
| return bool(response.data) |
| except Exception as e: |
| logger.error(f"Error storing embedding: {e}") |
| return False |