# backend/app/repositories/qdrant_repository.py from typing import Optional, List from qdrant_client import AsyncQdrantClient from qdrant_client.http import models from app.core.config import settings class QdrantRepository: def __init__(self): # Initialisation du client asynchrone self.client = AsyncQdrantClient( url=settings.qdrant_url, # api_key=getattr(settings, "qdrant_api_key", None) # Qdrant Cloud ) self.collection_name = settings.qdrant_collection async def init_collection(self, vector_size: int = 1024): """ Crée la collection si elle n'existe pas encore. 1024 correspond à la taille des vecteurs de Snowflake Arctic Embed 2.0 (large). """ exists = await self.client.collection_exists(collection_name=self.collection_name) if not exists: print(f"[Qdrant] Création de la collection '{self.collection_name}'...") await self.client.create_collection( collection_name=self.collection_name, vectors_config=models.VectorParams( size=vector_size, distance=models.Distance.COSINE ) ) print("[Qdrant] Collection créée avec succès.") else: print(f"[Qdrant] La collection '{self.collection_name}' existe déjà.") async def search_similar_project(self, query_vector: List[float], limit: int = 1) -> Optional[dict]: """ Effectue la vraie recherche vectorielle. Note : On passe un 'query_vector' (généré par ton embedding_service) et non du texte brut. """ try: results = await self.client.search( collection_name=self.collection_name, query_vector=query_vector, limit=limit ) if results: # On retourne le payload (les métadonnées du projet) du meilleur match return results[0].payload return None except Exception as e: print(f"[Qdrant] Erreur lors de la recherche : {e}") return None async def close(self): """Ferme proprement la connexion au client""" await self.client.close()