from langchain.embeddings.base import Embeddings from langchain_community.vectorstores import Qdrant from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store from langflow.helpers.data import docs_to_data from langflow.io import ( DataInput, DropdownInput, HandleInput, IntInput, MultilineInput, SecretStrInput, StrInput, ) from langflow.schema import Data class QdrantVectorStoreComponent(LCVectorStoreComponent): display_name = "Qdrant" description = "Qdrant Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/qdrant" icon = "Qdrant" inputs = [ StrInput(name="collection_name", display_name="Collection Name", required=True), StrInput(name="host", display_name="Host", value="localhost", advanced=True), IntInput(name="port", display_name="Port", value=6333, advanced=True), IntInput(name="grpc_port", display_name="gRPC Port", value=6334, advanced=True), SecretStrInput(name="api_key", display_name="API Key", advanced=True), StrInput(name="prefix", display_name="Prefix", advanced=True), IntInput(name="timeout", display_name="Timeout", advanced=True), StrInput(name="path", display_name="Path", advanced=True), StrInput(name="url", display_name="URL", advanced=True), DropdownInput( name="distance_func", display_name="Distance Function", options=["Cosine", "Euclidean", "Dot Product"], value="Cosine", advanced=True, ), StrInput(name="content_payload_key", display_name="Content Payload Key", value="page_content", advanced=True), StrInput(name="metadata_payload_key", display_name="Metadata Payload Key", value="metadata", advanced=True), MultilineInput(name="search_query", display_name="Search Query"), DataInput( name="ingest_data", display_name="Ingest Data", is_list=True, ), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), IntInput( name="number_of_results", display_name="Number of Results", info="Number of results to return.", value=4, advanced=True, ), ] @check_cached_vector_store def build_vector_store(self) -> Qdrant: qdrant_kwargs = { "collection_name": self.collection_name, "content_payload_key": self.content_payload_key, "metadata_payload_key": self.metadata_payload_key, } server_kwargs = { "host": self.host or None, "port": int(self.port), # Ensure port is an integer "grpc_port": int(self.grpc_port), # Ensure grpc_port is an integer "api_key": self.api_key, "prefix": self.prefix, # Ensure timeout is an integer "timeout": int(self.timeout) if self.timeout else None, "path": self.path or None, "url": self.url or None, } server_kwargs = {k: v for k, v in server_kwargs.items() if v is not None} documents = [] for _input in self.ingest_data or []: if isinstance(_input, Data): documents.append(_input.to_lc_document()) else: documents.append(_input) if not isinstance(self.embedding, Embeddings): msg = "Invalid embedding object" raise TypeError(msg) if documents: qdrant = Qdrant.from_documents(documents, embedding=self.embedding, **qdrant_kwargs, **server_kwargs) else: from qdrant_client import QdrantClient client = QdrantClient(**server_kwargs) qdrant = Qdrant(embeddings=self.embedding, client=client, **qdrant_kwargs) return qdrant def search_documents(self) -> list[Data]: vector_store = self.build_vector_store() if self.search_query and isinstance(self.search_query, str) and self.search_query.strip(): docs = vector_store.similarity_search( query=self.search_query, k=self.number_of_results, ) data = docs_to_data(docs) self.status = data return data return []