ats-system / backend /database /supabase_db.py
Aju360's picture
Add initial project structure with configuration, logging, and API setup
dac85e7
Raw
History Blame Contribute Delete
4.04 kB
import logging
import httpx
import json
from datetime import datetime, timezone
from typing import List, Optional, Dict
logger = logging.getLogger('ats_resume_scorer')
from backend.core.config import SUPABASE_URL, SUPABASE_KEY
def _get_headers():
if not SUPABASE_URL or not SUPABASE_KEY:
return None
return {
"apikey": SUPABASE_KEY,
"Authorization": f"Bearer {SUPABASE_KEY}",
"Content-Type": "application/json",
"Prefer": "return=representation"
}
async def save_analysis(user_id: str, filename: str, analysis_result: Dict) -> Optional[str]:
headers = _get_headers()
if not headers:
return None
def _json_default(o):
if hasattr(o, 'model_dump'):
return o.model_dump()
return str(o)
serializable_result = json.loads(json.dumps(analysis_result, default=_json_default))
doc = {
"user_id": user_id,
"filename": filename,
"ats_score": serializable_result.get("ats_score", 0),
"keyword_match": serializable_result.get("keyword_match", 0),
"missing_keywords": serializable_result.get("missing_keywords", []),
"created_at": datetime.now(timezone.utc).isoformat(),
"analysis_result": serializable_result,
}
url = f"{SUPABASE_URL.rstrip('/')}/rest/v1/analyses"
try:
async with httpx.AsyncClient() as client:
response = await client.post(url, headers=headers, json=doc)
response.raise_for_status()
data = response.json()
if data and len(data) > 0:
inserted_id = str(data[0].get("id"))
logger.info(f"Saved analysis for user {user_id}: {inserted_id}")
return inserted_id
return None
except Exception as exc:
logger.error(f"Failed to save analysis to Supabase: {exc}")
return None
async def get_user_history(user_id: str) -> List[Dict]:
headers = _get_headers()
if not headers:
return []
url = f"{SUPABASE_URL.rstrip('/')}/rest/v1/analyses"
try:
async with httpx.AsyncClient() as client:
response = await client.get(
url,
headers=headers,
params={
"user_id": f"eq.{user_id}",
"order": "created_at.desc"
}
)
response.raise_for_status()
docs = response.json()
results = []
for doc in docs:
results.append({
"id": str(doc.get("id")),
"filename": doc.get("filename", "resume"),
"resume_name": doc.get("filename", "resume"),
"job_title": "Software Engineer",
"ats_score": doc.get("ats_score", 0),
"keyword_match": doc.get("keyword_match", 0),
"missing_keywords": doc.get("missing_keywords", []),
"date": doc.get("created_at", ""),
"created_at": doc.get("created_at", ""),
"analysis_result": doc.get("analysis_result", {}),
})
return results
except Exception as exc:
logger.error(f"Failed to fetch history from Supabase: {exc}")
return []
async def delete_analysis(analysis_id: str, user_id: str) -> bool:
headers = _get_headers()
if not headers:
return False
url = f"{SUPABASE_URL.rstrip('/')}/rest/v1/analyses"
try:
async with httpx.AsyncClient() as client:
response = await client.delete(
url,
headers=headers,
params={
"id": f"eq.{analysis_id}",
"user_id": f"eq.{user_id}"
}
)
response.raise_for_status()
return True
except Exception as exc:
logger.error(f"Failed to delete analysis {analysis_id}: {exc}")
return False