HealthCare-API / api /services /database_interface.py
ryanxely's picture
KPI extraction
9b0ce22
Raw
History Blame Contribute Delete
6.3 kB
# Database interface for conversation and message storage using HF buckets
# JSONL format for scalability and future database migration
import json
from datetime import datetime
from typing import Optional, List, Dict
from huggingface_hub import HfApi
from api.config import settings
class ConversationDatabase:
"""Manages conversation and message storage in HF bucket using JSONL format"""
def __init__(self):
self.api = HfApi()
self.repo_id = settings.bucket.repo_id
self.repo_type = settings.bucket.repo_type
self.conversations_base = settings.bucket.conversations_base
def add_message_to_conversation(
self, user_id: str, conversation_id: str,
role: str, content: str,
language: str = "en",
symptoms: List[str] = [],
quick_replies: List[str] = []
) -> bool:
"""Add message to conversation JSONL file"""
try:
message = {
"timestamp": datetime.utcnow().isoformat(),
"role": role, # "user" or "assistant"
"content": content,
"language": language,
"symptoms": symptoms or [],
"quick_replies": quick_replies or []
}
# Read existing messages
messages_file = f"{self.conversations_base}{user_id}/{conversation_id}_messages.jsonl"
existing_content = ""
try:
existing_content = self.api.read_file_content(
repo_id=self.repo_id,
repo_type=self.repo_type,
filename=messages_file
)
except Exception:
# File doesn't exist yet
pass
# Append new message
new_content = existing_content
if new_content and not new_content.endswith('\n'):
new_content += '\n'
new_content += json.dumps(message)
# Upload updated file
self.api.upload_file(
path_or_fileobj=new_content.encode('utf-8'),
path_in_repo=messages_file,
repo_id=self.repo_id,
repo_type=self.repo_type,
commit_message=f"Add message to conversation {conversation_id}"
)
# Update conversation metadata with last_updated timestamp
self._update_conversation_timestamp(user_id, conversation_id)
return True
except Exception as e:
print(f"Error adding message: {e}")
return False
def get_conversation_messages(self, user_id: str, conversation_id: str) -> List[Dict]:
"""Read all messages from conversation JSONL file"""
try:
messages_file = f"{self.conversations_base}{user_id}/{conversation_id}_messages.jsonl"
content = self.api.read_file_content(
repo_id=self.repo_id,
repo_type=self.repo_type,
filename=messages_file
)
messages = []
for line in content.strip().split('\n'):
if line:
messages.append(json.loads(line))
return messages
except Exception:
# File doesn't exist or error reading
return []
def save_diagnosis_to_conversation(self, user_id: str, conversation_id: str, diagnosis: Dict, recommendations: str = "") -> bool:
"""Save diagnosis results to conversation diagnosis file"""
try:
diagnosis_file = f"{self.conversations_base}{user_id}/{conversation_id}_diagnosis.json"
diagnosis_data = {
"timestamp": datetime.utcnow().isoformat(),
"diagnosis": diagnosis,
"recommendations": recommendations
}
self.api.upload_file(
path_or_fileobj=json.dumps(diagnosis_data, indent=2).encode('utf-8'),
path_in_repo=diagnosis_file,
repo_id=self.repo_id,
repo_type=self.repo_type,
commit_message=f"Add diagnosis to conversation {conversation_id}"
)
# Update conversation metadata
self._update_conversation_timestamp(user_id, conversation_id)
return True
except Exception as e:
print(f"Error saving diagnosis: {e}")
return False
def get_diagnosis_from_conversation(self, user_id: str, conversation_id: str) -> Optional[Dict]:
"""Read diagnosis results from conversation diagnosis file"""
try:
diagnosis_file = f"{self.conversations_base}{user_id}/{conversation_id}_diagnosis.json"
content = self.api.read_file_content(
repo_id=self.repo_id,
repo_type=self.repo_type,
filename=diagnosis_file
)
return json.loads(content)
except Exception:
# Diagnosis file doesn't exist
return None
def _update_conversation_timestamp(self, user_id: str, conversation_id: str):
"""Update the last_updated timestamp in conversation metadata"""
try:
metadata_file = f"{self.conversations_base}{user_id}/{conversation_id}_metadata.json"
metadata = {}
# Try to read existing metadata
try:
content = self.api.read_file_content(
repo_id=self.repo_id,
repo_type=self.repo_type,
filename=metadata_file
)
metadata = json.loads(content)
except Exception:
pass
# Update timestamp
metadata["last_updated"] = datetime.utcnow().isoformat()
self.api.upload_file(
path_or_fileobj=json.dumps(metadata, indent=2).encode('utf-8'),
path_in_repo=metadata_file,
repo_id=self.repo_id,
repo_type=self.repo_type,
commit_message=f"Update conversation {conversation_id} timestamp"
)
except Exception as e:
print(f"Error updating conversation timestamp: {e}")
# Singleton instance
conversation_db = ConversationDatabase()