Skip to content

Commit e56f94f

Browse files
committed
feat: Qdrant Vector Store
Signed-off-by: Anush008 <anushshetty90@gmail.com>
1 parent f8c790e commit e56f94f

File tree

9 files changed

+469
-166
lines changed

9 files changed

+469
-166
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ Options for indexing existing context history or enabling real-time indexing new
535535
- ChromaVectorStore
536536
- ElasticsearchStore
537537
- PinecodeVectorStore
538+
- QdrantVectorStore
538539
- RedisVectorStore
539540
- SimpleVectorStore
540541
```
@@ -2973,6 +2974,7 @@ You can provide a single URI in the form of: `{scheme}://{user}:{password}@{host
29732974
- ChromaVectorStore
29742975
- ElasticsearchStore
29752976
- PinecodeVectorStore
2977+
- QdrantVectorStore
29762978
- RedisVectorStore
29772979
- SimpleVectorStore
29782980
```
@@ -3003,6 +3005,15 @@ Keyword arguments for Pinecone(`**kwargs`):
30033005
- `api_key`
30043006
- index_name (default: current index ID, already set, not required)
30053007

3008+
**QdrantVectorStore**
3009+
3010+
Keyword arguments for QdrantVectorStore(`**kwargs`):
3011+
3012+
- `url` - str, default: `http://localhost:6333`
3013+
- `api_key` - str, default: `None` (for Qdrant Cloud)
3014+
- `collection_name` (default: current index ID, already set, not required)
3015+
- any other keyword arguments provided on list
3016+
30063017
**RedisVectorStore**
30073018

30083019
Keyword arguments for RedisVectorStore(`**kwargs`):
@@ -3500,6 +3511,7 @@ You can create a custom vector store provider or data loader for your data and d
35003511
from pygpt_net.provider.vector_stores.chroma import ChromaProvider
35013512
from pygpt_net.provider.vector_stores.elasticsearch import ElasticsearchProvider
35023513
from pygpt_net.provider.vector_stores.pinecode import PinecodeProvider
3514+
from pygpt_net.provider.vector_stores.qdrant import QdrantProvider
35033515
from pygpt_net.provider.vector_stores.redis import RedisProvider
35043516
from pygpt_net.provider.vector_stores.simple import SimpleProvider
35053517

@@ -3509,6 +3521,7 @@ def run(**kwargs):
35093521
launcher.add_vector_store(ChromaProvider())
35103522
launcher.add_vector_store(ElasticsearchProvider())
35113523
launcher.add_vector_store(PinecodeProvider())
3524+
launcher.add_vector_store(QdrantProvider())
35123525
launcher.add_vector_store(RedisProvider())
35133526
launcher.add_vector_store(SimpleProvider())
35143527

docs/source/configuration.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ Vector stores
729729
* ChromaVectorStore
730730
* ElasticsearchStore
731731
* PinecodeVectorStore
732+
* QdrantVectorStore
732733
* RedisVectorStore
733734
* SimpleVectorStore
734735

@@ -758,6 +759,15 @@ Keyword arguments for Pinecone(``**kwargs``):
758759
* ``api_key``
759760
* index_name (default: current index ID, already set, not required)
760761

762+
**QdrantVectorStore**
763+
764+
Keyword arguments for QdrantVectorStore(``**kwargs``):
765+
766+
* ``url`` - str, default: `http://localhost:6333`
767+
* ``api_key`` - str, default: `None` (for Qdrant Cloud)
768+
* ``collection_name`` (default: current index ID, already set, not required)
769+
* any other keyword arguments provided on list
770+
761771
**RedisVectorStore**
762772

763773
Keyword arguments for RedisVectorStore(``**kwargs``):

docs/source/extending.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ You can create a custom vector store provider or data loader for your data and d
412412
from pygpt_net.provider.vector_stores.chroma import ChromaProvider
413413
from pygpt_net.provider.vector_stores.elasticsearch import ElasticsearchProvider
414414
from pygpt_net.provider.vector_stores.pinecode import PinecodeProvider
415+
from pygpt_net.provider.vector_stores.qdrant import QdrantProvider
415416
from pygpt_net.provider.vector_stores.redis import RedisProvider
416417
from pygpt_net.provider.vector_stores.simple import SimpleProvider
417418
@@ -421,6 +422,7 @@ You can create a custom vector store provider or data loader for your data and d
421422
launcher.add_vector_store(ChromaProvider())
422423
launcher.add_vector_store(ElasticsearchProvider())
423424
launcher.add_vector_store(PinecodeProvider())
425+
launcher.add_vector_store(QdrantProvider())
424426
launcher.add_vector_store(RedisProvider())
425427
launcher.add_vector_store(SimpleProvider())
426428

poetry.lock

Lines changed: 227 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ pygame = "^2.6.1"
106106
pypdf = "6.1.0"
107107
pynput = "^1.8.1"
108108
pyserial = "^3.5"
109+
llama-index-vector-stores-qdrant = "^0.8.5"
109110
PySide6 = "6.9.1"
110111
python-markdown-math = "^0.8"
111112
qasync = "^0.27.1"

requirements.txt

Lines changed: 96 additions & 130 deletions
Large diffs are not rendered by default.

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
'llama-index-vector-stores-chroma>=0.4.2,<0.5.0',
9191
'llama-index-vector-stores-elasticsearch==0.4.0',
9292
'llama-index-vector-stores-pinecone>=0.6.0,<0.7.0',
93+
'llama-index-vector-stores-qdrant>=0.8.0,<0.9.0',
9394
'llama-index-vector-stores-redis>=0.4.0,<0.5.0',
9495
'llama-index-readers-chatgpt-plugin>=0.3.0,<0.4.0',
9596
'llama-index-readers-database>=0.3.0,<0.4.0',

src/pygpt_net/app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ def open_wrapper(file, mode='r', *args, **kwargs):
146146
from pygpt_net.provider.vector_stores.chroma import ChromaProvider
147147
from pygpt_net.provider.vector_stores.elasticsearch import ElasticsearchProvider
148148
from pygpt_net.provider.vector_stores.pinecode import PinecodeProvider
149+
from pygpt_net.provider.vector_stores.qdrant import QdrantProvider
149150
from pygpt_net.provider.vector_stores.redis import RedisProvider
150151
from pygpt_net.provider.vector_stores.simple import SimpleProvider
151152

@@ -475,6 +476,7 @@ def run(**kwargs):
475476
launcher.add_vector_store(ChromaProvider())
476477
launcher.add_vector_store(ElasticsearchProvider())
477478
launcher.add_vector_store(PinecodeProvider())
479+
launcher.add_vector_store(QdrantProvider())
478480
launcher.add_vector_store(RedisProvider())
479481
launcher.add_vector_store(SimpleProvider())
480482

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
# ================================================== #
4+
# This file is a part of PYGPT package #
5+
# Website: https://pygpt.net #
6+
# GitHub: https://github.com/szczyglis-dev/py-gpt #
7+
# MIT License #
8+
# Created By : Marcin Szczygliński #
9+
# Updated Date: 2025.09.30 13:00:00 #
10+
# ================================================== #
11+
12+
import datetime
13+
import os.path
14+
from typing import Optional
15+
16+
from llama_index.core.indices.base import BaseIndex
17+
from llama_index.core import StorageContext
18+
19+
from pygpt_net.utils import parse_args
20+
from .base import BaseStore
21+
22+
23+
class QdrantProvider(BaseStore):
24+
def __init__(self, *args, **kwargs):
25+
super(QdrantProvider, self).__init__(*args, **kwargs)
26+
"""
27+
Qdrant vector store provider
28+
29+
:param args: args
30+
:param kwargs: kwargs
31+
"""
32+
self.window = kwargs.get('window', None)
33+
self.id = "QdrantVectorStore"
34+
self.prefix = "qdrant_" # prefix for index directory
35+
self.indexes = {}
36+
37+
def create(self, id: str):
38+
"""
39+
Create empty index
40+
41+
:param id: index name
42+
"""
43+
path = self.get_path(id)
44+
if not os.path.exists(path):
45+
os.makedirs(path, exist_ok=True)
46+
self.store(id)
47+
48+
def get_qdrant_store(self, id: str):
49+
"""
50+
Get Qdrant vector store
51+
52+
:param id: index name
53+
:return: QdrantVectorStore instance
54+
"""
55+
from llama_index.vector_stores.qdrant import QdrantVectorStore
56+
57+
additional_args = parse_args(
58+
self.window.core.config.get('llama.idx.storage.args', []),
59+
)
60+
61+
url = additional_args.get('url', 'http://localhost:6333')
62+
api_key = additional_args.get('api_key', '')
63+
64+
store_args = {k: v for k, v in additional_args.items() if k not in ['url', 'api_key', 'collection_name']}
65+
66+
return QdrantVectorStore(
67+
url=url,
68+
api_key=api_key,
69+
collection_name=id,
70+
**store_args
71+
)
72+
73+
def get(
74+
self,
75+
id: str,
76+
llm: Optional = None,
77+
embed_model: Optional = None,
78+
) -> BaseIndex:
79+
"""
80+
Get index
81+
82+
:param id: index name
83+
:param llm: LLM instance
84+
:param embed_model: Embedding model instance
85+
:return: index instance
86+
"""
87+
if not self.exists(id):
88+
self.create(id)
89+
vector_store = self.get_qdrant_store(id)
90+
storage_context = StorageContext.from_defaults(
91+
vector_store=vector_store,
92+
)
93+
self.indexes[id] = self.index_from_store(
94+
vector_store=vector_store,
95+
storage_context=storage_context,
96+
llm=llm,
97+
embed_model=embed_model,
98+
)
99+
return self.indexes[id]
100+
101+
def store(
102+
self,
103+
id: str,
104+
index: Optional[BaseIndex] = None
105+
):
106+
"""
107+
Store index
108+
109+
:param id: index name
110+
:param index: index instance
111+
"""
112+
path = self.get_path(id)
113+
os.makedirs(path, exist_ok=True)
114+
lock_file = os.path.join(path, 'store.lock')
115+
with open(lock_file, 'w') as f:
116+
f.write(id + ': ' + str(datetime.datetime.now()))
117+
self.indexes[id] = index

0 commit comments

Comments
 (0)