RAGChatbot / scripts /embedder.py
Shurem's picture
Add application file
45c5a08
Raw
History Blame Contribute Delete
2.82 kB
import os
from typing import List, Dict, Any, Optional
import logging
from openai import AsyncOpenAI
logger = logging.getLogger(__name__)
class Embedder:
def __init__(self):
"""
Initialize the embedder with OpenAI-compatible API
"""
# Use OpenAI-compatible endpoint for Gemini
base_url = os.getenv("OPENAI_BASE_URL", "https://generativelanguage.googleapis.com/v1beta/openai/")
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
raise ValueError("OPENAI_API_KEY environment variable is required")
self.client = AsyncOpenAI(
base_url=base_url,
api_key=api_key
)
# Use Gemini embedding model
self.model = os.getenv("EMBEDDING_MODEL", "text-embedding-004") # Default to a common embedding model
self.dimension = int(os.getenv("EMBEDDING_DIMENSION", "768")) # Default to 768
async def generate_embedding(self, text: str) -> List[float]:
"""
Generate embedding for a single text
"""
try:
response = await self.client.embeddings.create(
input=text,
model=self.model
)
embedding = response.data[0].embedding
return embedding
except Exception as e:
logger.error(f"Failed to generate embedding: {e}")
raise
async def generate_embeddings_batch(self, texts: List[str]) -> List[List[float]]:
"""
Generate embeddings for a batch of texts
"""
try:
# Process in smaller batches to avoid rate limits
batch_size = 20 # Typical safe batch size
all_embeddings = []
for i in range(0, len(texts), batch_size):
batch = texts[i:i + batch_size]
response = await self.client.embeddings.create(
input=batch,
model=self.model
)
batch_embeddings = [item.embedding for item in response.data]
all_embeddings.extend(batch_embeddings)
return all_embeddings
except Exception as e:
logger.error(f"Failed to generate embeddings batch: {e}")
raise
async def get_embedding_dimension(self) -> int:
"""
Get the dimension of the embeddings
"""
# Test with a short text to determine actual dimension
test_embedding = await self.generate_embedding("test")
return len(test_embedding)
# Lazy-initialized embedder instance
_embedder: Optional[Embedder] = None
def get_embedder() -> Embedder:
"""Get or create the Embedder instance (lazy initialization)"""
global _embedder
if _embedder is None:
_embedder = Embedder()
return _embedder