vicinity 0.2.1__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {vicinity-0.2.1 → vicinity-0.3.1}/PKG-INFO +75 -98
  2. {vicinity-0.2.1 → vicinity-0.3.1}/README.md +65 -97
  3. {vicinity-0.2.1 → vicinity-0.3.1}/pyproject.toml +10 -0
  4. {vicinity-0.2.1 → vicinity-0.3.1}/tests/test_vicinity.py +20 -0
  5. {vicinity-0.2.1 → vicinity-0.3.1}/uv.lock +19 -1
  6. vicinity-0.3.1/vicinity/__init__.py +8 -0
  7. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/backends/annoy.py +28 -24
  8. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/backends/base.py +7 -0
  9. vicinity-0.3.1/vicinity/backends/basic.py +223 -0
  10. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/backends/faiss.py +33 -51
  11. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/backends/hnsw.py +19 -6
  12. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/backends/pynndescent.py +21 -12
  13. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/backends/usearch.py +26 -22
  14. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/utils.py +39 -0
  15. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/version.py +1 -1
  16. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/vicinity.py +78 -2
  17. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity.egg-info/PKG-INFO +75 -98
  18. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity.egg-info/requires.txt +10 -0
  19. vicinity-0.2.1/vicinity/__init__.py +0 -7
  20. vicinity-0.2.1/vicinity/backends/basic.py +0 -149
  21. {vicinity-0.2.1 → vicinity-0.3.1}/.github/workflows/ci.yaml +0 -0
  22. {vicinity-0.2.1 → vicinity-0.3.1}/.gitignore +0 -0
  23. {vicinity-0.2.1 → vicinity-0.3.1}/.pre-commit-config.yaml +0 -0
  24. {vicinity-0.2.1 → vicinity-0.3.1}/LICENSE +0 -0
  25. {vicinity-0.2.1 → vicinity-0.3.1}/Makefile +0 -0
  26. {vicinity-0.2.1 → vicinity-0.3.1}/setup.cfg +0 -0
  27. {vicinity-0.2.1 → vicinity-0.3.1}/tests/conftest.py +0 -0
  28. {vicinity-0.2.1 → vicinity-0.3.1}/tests/test_utils.py +0 -0
  29. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/backends/__init__.py +0 -0
  30. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/datatypes.py +0 -0
  31. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity/py.typed +0 -0
  32. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity.egg-info/SOURCES.txt +0 -0
  33. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity.egg-info/dependency_links.txt +0 -0
  34. {vicinity-0.2.1 → vicinity-0.3.1}/vicinity.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vicinity
3
- Version: 0.2.1
3
+ Version: 0.3.1
4
4
  Summary: Lightweight Nearest Neighbors with Flexible Backends
5
5
  Author-email: Stéphan Tulkens <stephantul@gmail.com>, Thomas van Dongen <thomas123@live.nl>
6
6
  License: MIT License
@@ -67,10 +67,19 @@ Provides-Extra: faiss
67
67
  Requires-Dist: faiss-cpu; extra == "faiss"
68
68
  Provides-Extra: usearch
69
69
  Requires-Dist: usearch; extra == "usearch"
70
+ Provides-Extra: all
71
+ Requires-Dist: hnswlib; extra == "all"
72
+ Requires-Dist: pynndescent>=0.5.10; extra == "all"
73
+ Requires-Dist: numba>=0.59.0; extra == "all"
74
+ Requires-Dist: llvmlite>=0.42.0; extra == "all"
75
+ Requires-Dist: numpy>=1.24.0; extra == "all"
76
+ Requires-Dist: annoy; extra == "all"
77
+ Requires-Dist: faiss-cpu; extra == "all"
78
+ Requires-Dist: usearch; extra == "all"
70
79
 
71
80
  <div align="center">
72
81
 
73
- # Vicinity: The Lightweight Vector Store
82
+ # Vicinity: Lightweight Nearest Neighbors
74
83
 
75
84
  </div>
76
85
 
@@ -87,18 +96,21 @@ Requires-Dist: usearch; extra == "usearch"
87
96
  </a>
88
97
  <a href="https://github.com/MinishLab/vicinity/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License - MIT"></a>
89
98
  </h2>
99
+
100
+ [Quickstart](#quickstart) •
101
+ [Main Features](#main-features) •
102
+ [Supported Backends](#supported-backends) •
103
+ [Installation](#installation)
104
+
90
105
  </div>
91
106
 
92
107
 
93
- ## Table of contents
108
+ Vicinity is a light-weight, low-dependency vector store. It provides a simple and intuitive interface for nearest neighbor search, with support for different backends and evaluation.
109
+
110
+ There are many nearest neighbors packages and methods out there. However, we found it difficult to compare them. Every package has its own interface, quirks, and limitations, and learning a new package can be time-consuming. In addition to that, how do you effectively evaluate different packages? How do you know which one is the best for your use case?
94
111
 
95
- - [Quickstart](#quickstart)
96
- - [Main Features](#main-features)
97
- - [Supported Backends](#supported-backends)
98
- - [Backend Parameters](#backend-parameters)
99
- - [Usage](#usage)
100
112
 
101
- Vicinity is the lightest-weight vector store. Just put in some vectors, calculate query vectors, and off you go. It provides a simple and intuitive API for nearest neighbor search, with support for different backends.
113
+ This is where Vicinity comes in. Instead of learning a new interface for each new package or backend, Vicinity provides a unified interface for all backends. This allows you to easily experiment with different indexing methods and distance metrics and choose the best one for your use case. Vicinity also provides a simple way to evaluate the performance of different backends, allowing you to measure the queries per second and recall.
102
114
 
103
115
  ## Quickstart
104
116
 
@@ -106,50 +118,80 @@ Install the package with:
106
118
  ```bash
107
119
  pip install vicinity
108
120
  ```
121
+ Optinally, [install any of the supported backends](#installation), or simply install all of them with:
122
+ ```bash
123
+ pip install vicinity[all]
124
+ ```
109
125
 
110
126
 
111
127
  The following code snippet demonstrates how to use Vicinity for nearest neighbor search:
112
128
  ```python
113
129
  import numpy as np
114
- from vicinity import Vicinity
115
- from vicinity.datatypes import Backend
130
+ from vicinity import Vicinity, Backend, Metric
116
131
 
117
132
  # Create some dummy data
118
133
  items = ["triforce", "master sword", "hylian shield", "boomerang", "hookshot"]
119
134
  vectors = np.random.rand(len(items), 128)
120
135
 
121
- # Initialize the Vicinity instance (using the basic backend)
122
- vicinity = Vicinity.from_vectors_and_items(vectors=vectors, items=items, backend_type=Backend.BASIC)
136
+ # Initialize the Vicinity instance (using the basic backend and cosine metric)
137
+ vicinity = Vicinity.from_vectors_and_items(vectors=vectors, items=items, backend_type=Backend.BASIC, metric=Metric.COSINE)
123
138
 
124
- # Query for nearest neighbors with a top-k search
139
+ # Create a query vector
125
140
  query_vector = np.random.rand(128)
141
+
142
+ # Query for nearest neighbors with a top-k search
126
143
  results = vicinity.query([query_vector], k=3)
127
144
 
128
145
  # Query for nearest neighbors with a threshold search
129
146
  results = vicinity.query_threshold([query_vector], threshold=0.9)
147
+ ```
130
148
 
131
- # Save the vector store
149
+ Saving and loading a vector store:
150
+ ```python
132
151
  vicinity.save('my_vector_store')
133
-
134
- # Load the vector store
135
152
  vicinity = Vicinity.load('my_vector_store')
136
153
  ```
137
154
 
155
+ Evaluating a backend:
156
+ ```python
157
+ # Use the first 1000 vectors as query vectors
158
+ query_vectors = vectors[:1000]
159
+
160
+ # Evaluate the Vicinity instance by measuring the queries per second and recall
161
+ qps, recall = vicinity.evaluate(
162
+ full_vectors=vectors,
163
+ query_vectors=query_vectors,
164
+ )
165
+ ```
166
+
138
167
  ## Main Features
139
168
  Vicinity provides the following features:
140
169
  - Lightweight: Minimal dependencies and fast performance.
141
170
  - Flexible Backend Support: Use different backends for vector storage and search.
142
171
  - Serialization: Save and load vector stores for persistence.
172
+ - Evaluation: Easily evaluate the performance of different backends.
143
173
  - Easy to Use: Simple and intuitive API.
144
174
 
145
175
  ## Supported Backends
146
176
  The following backends are supported:
147
- - `BASIC`: A simple flat index for vector storage and search.
177
+ - `BASIC`: A simple (exact matching) flat index for vector storage and search.
148
178
  - [HNSW](https://github.com/nmslib/hnswlib): Hierarchical Navigable Small World Graph (HNSW) for ANN search using hnswlib.
149
- - [FAISS](https://github.com/facebookresearch/faiss): ANN search using FAISS. All FAISS indexes are supported.
179
+ - [USEARCH](https://github.com/unum-cloud/usearch): ANN search using Usearch. This uses a highly optimized version of the HNSW algorithm.
150
180
  - [ANNOY](https://github.com/spotify/annoy): "Approximate Nearest Neighbors Oh Yeah" for approximate nearest neighbor search.
151
181
  - [PYNNDescent](https://github.com/lmcinnes/pynndescent): ANN search using PyNNDescent.
152
- - [USEARCH](https://github.com/unum-cloud/usearch): ANN search using Usearch. This uses a highly optimized version of the HNSW algorithm.
182
+ - [FAISS](https://github.com/facebookresearch/faiss): All FAISS indexes are supported:
183
+ - `flat`: Exact search.
184
+ - `ivf`: Inverted file search.
185
+ - `hnsw`: Hierarchical Navigable Small World Graph.
186
+ - `lsh`: Locality Sensitive Hashing.
187
+ - `scalar`: Scalar quantizer.
188
+ - `pq`: Product Quantizer.
189
+ - `ivf_scalar`: Inverted file search with scalar quantizer.
190
+ - `ivfpq`: Inverted file search with product quantizer.
191
+ - `ivfpqr`: Inverted file search with product quantizer and refinement.
192
+
193
+
194
+
153
195
 
154
196
  NOTE: the ANN backends do not support dynamic deletion. To delete items, you need to recreate the index. Insertion is supported in the following backends: `FAISS`, `HNSW`, and `Usearch`. The `BASIC` backend supports both insertion and deletion.
155
197
 
@@ -178,87 +220,22 @@ NOTE: the ANN backends do not support dynamic deletion. To delete items, you nee
178
220
  | | `expansion_search` | Number of candidates considered during search. | `64` |
179
221
 
180
222
 
223
+ ## Installation
224
+ The following installation options are available:
225
+ ```bash
226
+ # Install the base package
227
+ pip install vicinity
181
228
 
182
- ## Usage
183
-
184
- <details>
185
- <summary> Creating a Vector Store
186
- </summary>
187
- <br>
188
-
189
- You can create a Vicinity instance by providing items and their corresponding vectors:
190
-
191
-
192
- ```python
193
- from vicinity import Vicinity
194
- import numpy as np
195
-
196
- items = ["triforce", "master sword", "hylian shield", "boomerang", "hookshot"]
197
- vectors = np.random.rand(len(items), 128)
198
-
199
- vicinity = Vicinity.from_vectors_and_items(vectors=vectors, items=items)
200
- ```
201
-
202
- </details>
203
-
204
- <details>
205
- <summary> Querying
206
- </summary>
207
- <br>
208
-
209
- Find the k nearest neighbors for a given vector:
210
-
211
- ```python
212
- query_vector = np.random.rand(128)
213
- results = vicinity.query([query_vector], k=3)
214
- ```
215
-
216
- Find all neighbors within a given threshold:
217
-
218
- ```python
219
- query_vector = np.random.rand(128)
220
- results = vicinity.query_threshold([query_vector], threshold=0.9)
221
- ```
222
- </details>
223
-
224
- <details>
225
-
226
- <summary> Inserting and Deleting Items
227
- </summary>
228
- <br>
229
-
230
- Insert new items:
231
-
232
- ```python
233
- new_items = ["ocarina", "bow"]
234
- new_vectors = np.random.rand(2, 128)
235
- vicinity.insert(new_items, new_vectors)
236
- ```
237
-
238
- Delete items:
239
-
240
- ```python
241
- vicinity.delete(["hookshot"])
242
- ```
243
- </details>
244
-
245
- <details>
246
- <summary> Saving and Loading
247
- </summary>
248
- <br>
249
-
250
- Save the vector store:
251
-
252
- ```python
253
- vicinity.save('my_vector_store')
254
- ```
255
-
256
- Load the vector store:
229
+ # Install all backends
230
+ pip install vicinity[all]
257
231
 
258
- ```python
259
- vicinity = Vicinity.load('my_vector_store')
232
+ # Install specific backends
233
+ pip install vicinity[annoy]
234
+ pip install vicinity[faiss]
235
+ pip install vicinity[hnsw]
236
+ pip install vicinity[pynndescent]
237
+ pip install vicinity[usearch]
260
238
  ```
261
- </details>
262
239
 
263
240
  ## License
264
241
 
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- # Vicinity: The Lightweight Vector Store
3
+ # Vicinity: Lightweight Nearest Neighbors
4
4
 
5
5
  </div>
6
6
 
@@ -17,18 +17,21 @@
17
17
  </a>
18
18
  <a href="https://github.com/MinishLab/vicinity/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License - MIT"></a>
19
19
  </h2>
20
+
21
+ [Quickstart](#quickstart) •
22
+ [Main Features](#main-features) •
23
+ [Supported Backends](#supported-backends) •
24
+ [Installation](#installation)
25
+
20
26
  </div>
21
27
 
22
28
 
23
- ## Table of contents
29
+ Vicinity is a light-weight, low-dependency vector store. It provides a simple and intuitive interface for nearest neighbor search, with support for different backends and evaluation.
30
+
31
+ There are many nearest neighbors packages and methods out there. However, we found it difficult to compare them. Every package has its own interface, quirks, and limitations, and learning a new package can be time-consuming. In addition to that, how do you effectively evaluate different packages? How do you know which one is the best for your use case?
24
32
 
25
- - [Quickstart](#quickstart)
26
- - [Main Features](#main-features)
27
- - [Supported Backends](#supported-backends)
28
- - [Backend Parameters](#backend-parameters)
29
- - [Usage](#usage)
30
33
 
31
- Vicinity is the lightest-weight vector store. Just put in some vectors, calculate query vectors, and off you go. It provides a simple and intuitive API for nearest neighbor search, with support for different backends.
34
+ This is where Vicinity comes in. Instead of learning a new interface for each new package or backend, Vicinity provides a unified interface for all backends. This allows you to easily experiment with different indexing methods and distance metrics and choose the best one for your use case. Vicinity also provides a simple way to evaluate the performance of different backends, allowing you to measure the queries per second and recall.
32
35
 
33
36
  ## Quickstart
34
37
 
@@ -36,50 +39,80 @@ Install the package with:
36
39
  ```bash
37
40
  pip install vicinity
38
41
  ```
42
+ Optinally, [install any of the supported backends](#installation), or simply install all of them with:
43
+ ```bash
44
+ pip install vicinity[all]
45
+ ```
39
46
 
40
47
 
41
48
  The following code snippet demonstrates how to use Vicinity for nearest neighbor search:
42
49
  ```python
43
50
  import numpy as np
44
- from vicinity import Vicinity
45
- from vicinity.datatypes import Backend
51
+ from vicinity import Vicinity, Backend, Metric
46
52
 
47
53
  # Create some dummy data
48
54
  items = ["triforce", "master sword", "hylian shield", "boomerang", "hookshot"]
49
55
  vectors = np.random.rand(len(items), 128)
50
56
 
51
- # Initialize the Vicinity instance (using the basic backend)
52
- vicinity = Vicinity.from_vectors_and_items(vectors=vectors, items=items, backend_type=Backend.BASIC)
57
+ # Initialize the Vicinity instance (using the basic backend and cosine metric)
58
+ vicinity = Vicinity.from_vectors_and_items(vectors=vectors, items=items, backend_type=Backend.BASIC, metric=Metric.COSINE)
53
59
 
54
- # Query for nearest neighbors with a top-k search
60
+ # Create a query vector
55
61
  query_vector = np.random.rand(128)
62
+
63
+ # Query for nearest neighbors with a top-k search
56
64
  results = vicinity.query([query_vector], k=3)
57
65
 
58
66
  # Query for nearest neighbors with a threshold search
59
67
  results = vicinity.query_threshold([query_vector], threshold=0.9)
68
+ ```
60
69
 
61
- # Save the vector store
70
+ Saving and loading a vector store:
71
+ ```python
62
72
  vicinity.save('my_vector_store')
63
-
64
- # Load the vector store
65
73
  vicinity = Vicinity.load('my_vector_store')
66
74
  ```
67
75
 
76
+ Evaluating a backend:
77
+ ```python
78
+ # Use the first 1000 vectors as query vectors
79
+ query_vectors = vectors[:1000]
80
+
81
+ # Evaluate the Vicinity instance by measuring the queries per second and recall
82
+ qps, recall = vicinity.evaluate(
83
+ full_vectors=vectors,
84
+ query_vectors=query_vectors,
85
+ )
86
+ ```
87
+
68
88
  ## Main Features
69
89
  Vicinity provides the following features:
70
90
  - Lightweight: Minimal dependencies and fast performance.
71
91
  - Flexible Backend Support: Use different backends for vector storage and search.
72
92
  - Serialization: Save and load vector stores for persistence.
93
+ - Evaluation: Easily evaluate the performance of different backends.
73
94
  - Easy to Use: Simple and intuitive API.
74
95
 
75
96
  ## Supported Backends
76
97
  The following backends are supported:
77
- - `BASIC`: A simple flat index for vector storage and search.
98
+ - `BASIC`: A simple (exact matching) flat index for vector storage and search.
78
99
  - [HNSW](https://github.com/nmslib/hnswlib): Hierarchical Navigable Small World Graph (HNSW) for ANN search using hnswlib.
79
- - [FAISS](https://github.com/facebookresearch/faiss): ANN search using FAISS. All FAISS indexes are supported.
100
+ - [USEARCH](https://github.com/unum-cloud/usearch): ANN search using Usearch. This uses a highly optimized version of the HNSW algorithm.
80
101
  - [ANNOY](https://github.com/spotify/annoy): "Approximate Nearest Neighbors Oh Yeah" for approximate nearest neighbor search.
81
102
  - [PYNNDescent](https://github.com/lmcinnes/pynndescent): ANN search using PyNNDescent.
82
- - [USEARCH](https://github.com/unum-cloud/usearch): ANN search using Usearch. This uses a highly optimized version of the HNSW algorithm.
103
+ - [FAISS](https://github.com/facebookresearch/faiss): All FAISS indexes are supported:
104
+ - `flat`: Exact search.
105
+ - `ivf`: Inverted file search.
106
+ - `hnsw`: Hierarchical Navigable Small World Graph.
107
+ - `lsh`: Locality Sensitive Hashing.
108
+ - `scalar`: Scalar quantizer.
109
+ - `pq`: Product Quantizer.
110
+ - `ivf_scalar`: Inverted file search with scalar quantizer.
111
+ - `ivfpq`: Inverted file search with product quantizer.
112
+ - `ivfpqr`: Inverted file search with product quantizer and refinement.
113
+
114
+
115
+
83
116
 
84
117
  NOTE: the ANN backends do not support dynamic deletion. To delete items, you need to recreate the index. Insertion is supported in the following backends: `FAISS`, `HNSW`, and `Usearch`. The `BASIC` backend supports both insertion and deletion.
85
118
 
@@ -108,87 +141,22 @@ NOTE: the ANN backends do not support dynamic deletion. To delete items, you nee
108
141
  | | `expansion_search` | Number of candidates considered during search. | `64` |
109
142
 
110
143
 
144
+ ## Installation
145
+ The following installation options are available:
146
+ ```bash
147
+ # Install the base package
148
+ pip install vicinity
111
149
 
112
- ## Usage
113
-
114
- <details>
115
- <summary> Creating a Vector Store
116
- </summary>
117
- <br>
118
-
119
- You can create a Vicinity instance by providing items and their corresponding vectors:
120
-
121
-
122
- ```python
123
- from vicinity import Vicinity
124
- import numpy as np
125
-
126
- items = ["triforce", "master sword", "hylian shield", "boomerang", "hookshot"]
127
- vectors = np.random.rand(len(items), 128)
128
-
129
- vicinity = Vicinity.from_vectors_and_items(vectors=vectors, items=items)
130
- ```
131
-
132
- </details>
133
-
134
- <details>
135
- <summary> Querying
136
- </summary>
137
- <br>
138
-
139
- Find the k nearest neighbors for a given vector:
140
-
141
- ```python
142
- query_vector = np.random.rand(128)
143
- results = vicinity.query([query_vector], k=3)
144
- ```
145
-
146
- Find all neighbors within a given threshold:
147
-
148
- ```python
149
- query_vector = np.random.rand(128)
150
- results = vicinity.query_threshold([query_vector], threshold=0.9)
151
- ```
152
- </details>
153
-
154
- <details>
155
-
156
- <summary> Inserting and Deleting Items
157
- </summary>
158
- <br>
159
-
160
- Insert new items:
161
-
162
- ```python
163
- new_items = ["ocarina", "bow"]
164
- new_vectors = np.random.rand(2, 128)
165
- vicinity.insert(new_items, new_vectors)
166
- ```
167
-
168
- Delete items:
169
-
170
- ```python
171
- vicinity.delete(["hookshot"])
172
- ```
173
- </details>
174
-
175
- <details>
176
- <summary> Saving and Loading
177
- </summary>
178
- <br>
179
-
180
- Save the vector store:
181
-
182
- ```python
183
- vicinity.save('my_vector_store')
184
- ```
185
-
186
- Load the vector store:
150
+ # Install all backends
151
+ pip install vicinity[all]
187
152
 
188
- ```python
189
- vicinity = Vicinity.load('my_vector_store')
153
+ # Install specific backends
154
+ pip install vicinity[annoy]
155
+ pip install vicinity[faiss]
156
+ pip install vicinity[hnsw]
157
+ pip install vicinity[pynndescent]
158
+ pip install vicinity[usearch]
190
159
  ```
191
- </details>
192
160
 
193
161
  ## License
194
162
 
@@ -52,6 +52,16 @@ pynndescent = [
52
52
  annoy = ["annoy"]
53
53
  faiss = ["faiss-cpu"]
54
54
  usearch = ["usearch"]
55
+ all = [
56
+ "hnswlib",
57
+ "pynndescent>=0.5.10",
58
+ "numba>=0.59.0",
59
+ "llvmlite>=0.42.0",
60
+ "numpy>=1.24.0",
61
+ "annoy",
62
+ "faiss-cpu",
63
+ "usearch"
64
+ ]
55
65
 
56
66
  [project.urls]
57
67
  "Homepage" = "https://github.com/MinishLab"
@@ -220,3 +220,23 @@ def test_vicinity_delete_and_query(vicinity_instance: Vicinity, items: list[str]
220
220
 
221
221
  # Check that the queried item is in the results
222
222
  assert "item3" in returned_items
223
+
224
+
225
+ def test_vicinity_evaluate(vicinity_instance: Vicinity, vectors: np.ndarray) -> None:
226
+ """
227
+ Test the evaluate method of the Vicinity instance.
228
+
229
+ :param vicinity_instance: A Vicinity instance.
230
+ :param vectors: The full dataset vectors used to build the index.
231
+ """
232
+ query_vectors = vectors[:10]
233
+ qps, recall = vicinity_instance.evaluate(vectors, query_vectors)
234
+
235
+ # Ensure the QPS and recall values are within valid ranges
236
+ assert qps > 0
237
+ assert 0 <= recall <= 1
238
+
239
+ # Test with an unsupported metric
240
+ vicinity_instance.backend.arguments.metric = "manhattan"
241
+ with pytest.raises(ValueError):
242
+ vicinity_instance.evaluate(vectors, query_vectors)
@@ -1087,7 +1087,7 @@ wheels = [
1087
1087
 
1088
1088
  [[package]]
1089
1089
  name = "vicinity"
1090
- version = "0.2.0"
1090
+ version = "0.3.0"
1091
1091
  source = { editable = "." }
1092
1092
  dependencies = [
1093
1093
  { name = "numpy" },
@@ -1096,6 +1096,16 @@ dependencies = [
1096
1096
  ]
1097
1097
 
1098
1098
  [package.optional-dependencies]
1099
+ all = [
1100
+ { name = "annoy" },
1101
+ { name = "faiss-cpu" },
1102
+ { name = "hnswlib" },
1103
+ { name = "llvmlite" },
1104
+ { name = "numba" },
1105
+ { name = "numpy" },
1106
+ { name = "pynndescent" },
1107
+ { name = "usearch" },
1108
+ ]
1099
1109
  annoy = [
1100
1110
  { name = "annoy" },
1101
1111
  ]
@@ -1127,24 +1137,32 @@ usearch = [
1127
1137
 
1128
1138
  [package.metadata]
1129
1139
  requires-dist = [
1140
+ { name = "annoy", marker = "extra == 'all'" },
1130
1141
  { name = "annoy", marker = "extra == 'annoy'" },
1131
1142
  { name = "black", marker = "extra == 'dev'" },
1143
+ { name = "faiss-cpu", marker = "extra == 'all'" },
1132
1144
  { name = "faiss-cpu", marker = "extra == 'faiss'" },
1145
+ { name = "hnswlib", marker = "extra == 'all'" },
1133
1146
  { name = "hnswlib", marker = "extra == 'hnsw'" },
1134
1147
  { name = "ipython", marker = "extra == 'dev'" },
1148
+ { name = "llvmlite", marker = "extra == 'all'", specifier = ">=0.42.0" },
1135
1149
  { name = "llvmlite", marker = "extra == 'pynndescent'", specifier = ">=0.42.0" },
1136
1150
  { name = "mypy", marker = "extra == 'dev'" },
1151
+ { name = "numba", marker = "extra == 'all'", specifier = ">=0.59.0" },
1137
1152
  { name = "numba", marker = "extra == 'pynndescent'", specifier = ">=0.59.0" },
1138
1153
  { name = "numpy" },
1154
+ { name = "numpy", marker = "extra == 'all'", specifier = ">=1.24.0" },
1139
1155
  { name = "numpy", marker = "extra == 'pynndescent'", specifier = ">=1.24.0" },
1140
1156
  { name = "orjson" },
1141
1157
  { name = "pre-commit", marker = "extra == 'dev'" },
1158
+ { name = "pynndescent", marker = "extra == 'all'", specifier = ">=0.5.10" },
1142
1159
  { name = "pynndescent", marker = "extra == 'pynndescent'", specifier = ">=0.5.10" },
1143
1160
  { name = "pytest", marker = "extra == 'dev'" },
1144
1161
  { name = "pytest-coverage", marker = "extra == 'dev'" },
1145
1162
  { name = "ruff", marker = "extra == 'dev'" },
1146
1163
  { name = "setuptools", marker = "extra == 'dev'" },
1147
1164
  { name = "tqdm" },
1165
+ { name = "usearch", marker = "extra == 'all'" },
1148
1166
  { name = "usearch", marker = "extra == 'usearch'" },
1149
1167
  ]
1150
1168
 
@@ -0,0 +1,8 @@
1
+ """Small vector store."""
2
+
3
+ from vicinity.datatypes import Backend
4
+ from vicinity.utils import Metric, normalize
5
+ from vicinity.version import __version__
6
+ from vicinity.vicinity import Vicinity
7
+
8
+ __all__ = ["Backend", "Metric", "Vicinity", "normalize", "__version__"]