""" Embedding utilities for QAFD-RAG. Provides embedding function wrappers and utilities. """ import asyncio from dataclasses import dataclass import numpy as np class UnlimitedSemaphore: """A no-op semaphore that doesn't limit concurrency.""" async def __aenter__(self): pass async def __aexit__(self, exc_type, exc, tb): pass @dataclass class EmbeddingFunc: """ Wrapper for embedding functions with rate limiting. Attributes: ----------- embedding_dim : int Dimension of the embedding vectors max_token_size : int Maximum token size for input text func : callable The async embedding function to wrap concurrent_limit : int Maximum concurrent calls (0 for unlimited) """ embedding_dim: int max_token_size: int func: callable concurrent_limit: int = 16 def __post_init__(self): if self.concurrent_limit != 0: self._semaphore = asyncio.Semaphore(self.concurrent_limit) else: self._semaphore = UnlimitedSemaphore() async def __call__(self, *args, **kwargs) -> np.ndarray: async with self._semaphore: return await self.func(*args, **kwargs) def wrap_embedding_func_with_attrs(**kwargs): """ Decorator to wrap an embedding function with EmbeddingFunc attributes. Parameters: ----------- **kwargs Arguments passed to EmbeddingFunc (embedding_dim, max_token_size, etc.) Returns: -------- EmbeddingFunc Wrapped embedding function """ def final_decro(func) -> EmbeddingFunc: new_func = EmbeddingFunc(**kwargs, func=func) return new_func return final_decro __all__ = [ "UnlimitedSemaphore", "EmbeddingFunc", "wrap_embedding_func_with_attrs", ]