Skip to content

Commit 4242a39

Browse files
committed
Add master test script for all usage example files
Run linter on client/python
1 parent a471138 commit 4242a39

20 files changed

Lines changed: 171 additions & 81 deletions

‎client/python/examples/all.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# This file is like a master test. Runs all the examples
2+
# Not exactly the purpose of the examples dir,
3+
# but helps in checking if any code updates haven't broken the API
4+
5+
from pathlib import Path
6+
import subprocess
7+
import pytest
8+
9+
# Didn't know I could do this with pytest, so cool
10+
# Just run: pytest ./all.py -v
11+
12+
EXAMPLES_DIR = Path(__file__).parent
13+
example_files = sorted(EXAMPLES_DIR.glob("*_usage.py"))
14+
15+
16+
@pytest.mark.parametrize(
17+
"script_path",
18+
example_files,
19+
ids=lambda p: p.stem,
20+
)
21+
def test(script_path):
22+
"""Run all example scripts to check if they crash or not"""
23+
result = subprocess.run(
24+
["python3", str(script_path)], capture_output=True, text=True
25+
)
26+
assert result.returncode == 0, (
27+
f"Script {script_path} failed with stderr:\n{result.stderr}"
28+
)

‎client/python/examples/async_batch_usage.py‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import asyncio
22

33
from vortexdb import AsyncVortexDB
4-
from vortexdb import DenseVector, Payload, Similarity, SearchQuery, to_dense_vectors
4+
from vortexdb import Payload, Similarity, SearchQuery, to_dense_vectors
55

66

77
async def main():
88
async with AsyncVortexDB(
99
grpc_url="localhost:50051",
1010
api_key="my-secret-password",
1111
) as db:
12-
1312
raw_vectors = [
1413
[0.1, 0.2, 0.3],
1514
[0.4, 0.5, 0.6],
@@ -83,4 +82,4 @@ async def main():
8382

8483

8584
if __name__ == "__main__":
86-
asyncio.run(main())
85+
asyncio.run(main())

‎client/python/examples/basic_usage.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from vortexdb import VortexDB
2-
from vortexdb import DenseVector, Payload, Similarity # from vortexdb.models
2+
from vortexdb import DenseVector, Payload, Similarity # from vortexdb.models
3+
34

45
def main():
56
# Initialize client
@@ -32,5 +33,6 @@ def main():
3233
# Close connection
3334
db.close()
3435

36+
3537
if __name__ == "__main__":
3638
main()

‎client/python/examples/batch_insert_usage.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from vortexdb import VortexDB
2-
from vortexdb import DenseVector, Payload, to_dense_vectors
2+
from vortexdb import Payload, to_dense_vectors
33

44

55
def main():
@@ -36,4 +36,4 @@ def main():
3636

3737

3838
if __name__ == "__main__":
39-
main()
39+
main()

‎client/python/examples/context_manager_usage.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from vortexdb import VortexDB, DenseVector, Payload, Similarity
22

3+
34
def main():
45
with VortexDB(
56
grpc_url="localhost:50051",
67
api_key="my-secret-password",
78
) as db:
8-
99
# Insert a vector
1010
point_id = db.insert(
1111
vector=DenseVector([0.1, 0.2, 0.3]),
@@ -30,5 +30,6 @@ def main():
3030
# At this point, the gRPC channel is closed automatically
3131
print("Connection closed")
3232

33+
3334
if __name__ == "__main__":
3435
main()

‎client/python/examples/search_query_usage.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from vortexdb import VortexDB
2-
from vortexdb import DenseVector, Similarity, SearchQuery, to_dense_vectors
2+
from vortexdb import Similarity, SearchQuery, to_dense_vectors
33

44

55
def main():
@@ -66,4 +66,4 @@ def main():
6666

6767

6868
if __name__ == "__main__":
69-
main()
69+
main()

‎client/python/pyproject.toml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ Repository = "https://github.com/sdslabs/VortexDB"
4242

4343
[tool.pytest.ini_options]
4444
testpaths = ["tests"]
45+
46+
[tool.ruff]
47+
exclude = ["vortexdb/grpc"]

‎client/python/tests/test_async_client.py‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55

66
from vortexdb.async_client import AsyncVortexDB
77
from vortexdb.async_connection import AsyncGRPCConnection
8-
from vortexdb.models import ContentType, DenseVector, Payload, Point, Similarity, SearchQuery
8+
from vortexdb.models import (
9+
ContentType,
10+
DenseVector,
11+
Payload,
12+
Point,
13+
Similarity,
14+
SearchQuery,
15+
)
916

1017

1118
@pytest.fixture
@@ -60,6 +67,7 @@ async def run():
6067

6168
# Batch Insert
6269

70+
6371
def test_async_batch_insert_success(client, mock_connection):
6472
async def run():
6573
response = Mock()
@@ -111,6 +119,7 @@ async def run():
111119

112120
# Get
113121

122+
114123
def test_async_get_point_success(client, mock_connection):
115124
async def run():
116125
proto_point = Mock()
@@ -143,6 +152,7 @@ async def run():
143152

144153
# Delete
145154

155+
146156
def test_async_delete_success(client, mock_connection):
147157
async def run():
148158
mock_connection.call.return_value = None
@@ -156,6 +166,7 @@ async def run():
156166

157167
# Search
158168

169+
159170
def test_async_search_success(client, mock_connection):
160171
async def run():
161172
mock_connection.call.return_value = Mock(
@@ -223,6 +234,7 @@ async def run():
223234

224235
# Batch Search
225236

237+
226238
def test_async_batch_search_full_tuple(client, mock_connection):
227239
async def run():
228240
mock_connection.call.return_value = Mock(
@@ -275,7 +287,9 @@ async def run():
275287
asyncio.run(run())
276288

277289

278-
def test_async_batch_search_vector_similarity_with_global_limit(client, mock_connection):
290+
def test_async_batch_search_vector_similarity_with_global_limit(
291+
client, mock_connection
292+
):
279293
async def run():
280294
mock_connection.call.return_value = Mock(
281295
results=[
@@ -343,6 +357,7 @@ async def run():
343357

344358
# Close / Context Manager
345359

360+
346361
def test_async_close_closes_connection(client, mock_connection):
347362
async def run():
348363
await client.close()
@@ -367,4 +382,4 @@ async def run():
367382

368383
conn.close.assert_awaited_once()
369384

370-
asyncio.run(run())
385+
asyncio.run(run())

‎client/python/tests/test_client.py‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
from vortexdb.client import VortexDB
55
from vortexdb.connection import GRPCConnection
66
from vortexdb.models import DenseVector, Payload, Similarity, ContentType, Point
7-
from vortexdb.exceptions import InvalidArgumentError
87
from vortexdb.models import SearchQuery
98

109

11-
1210
# Fixtures for a mock connection and client layer
1311

12+
1413
@pytest.fixture
1514
def mock_connection(monkeypatch):
1615
"""
@@ -31,6 +30,7 @@ def client(mock_connection):
3130

3231
# Insert
3332

33+
3434
def test_insert_success(client, mock_connection):
3535
response = Mock()
3636
response.id = Mock()
@@ -56,6 +56,7 @@ def test_insert_rejects_invalid_vector(client):
5656

5757
# Batch Insert
5858

59+
5960
def test_batch_insert_success(client, mock_connection):
6061
response = Mock()
6162
response.ids = [
@@ -70,17 +71,20 @@ def test_batch_insert_success(client, mock_connection):
7071
result = client.batch_insert(items=items)
7172
assert result == ["p1", "p2"]
7273

74+
7375
def test_batch_insert_invalid_items_type(client):
7476
with pytest.raises(TypeError):
7577
client.batch_insert(items="not-a-list")
7678

79+
7780
def test_batch_insert_invalid_tuple_structure(client):
7881
items = [
7982
(DenseVector([1, 2, 3]),), # only one element
8083
]
8184
with pytest.raises(TypeError):
8285
client.batch_insert(items=items)
8386

87+
8488
def test_batch_insert_invalid_vector(client):
8589
items = [
8690
([1, 2, 3], Payload.text("a")), # not DenseVector
@@ -91,6 +95,7 @@ def test_batch_insert_invalid_vector(client):
9195

9296
# Get
9397

98+
9499
def test_get_point_success(client, mock_connection):
95100
proto_point = Mock()
96101
proto_point.id.id.value = "point-123"
@@ -117,6 +122,7 @@ def test_get_point_not_found(client, mock_connection):
117122

118123
# Delete
119124

125+
120126
def test_delete_success(client, mock_connection):
121127
mock_connection.call.return_value = None
122128

@@ -127,6 +133,7 @@ def test_delete_success(client, mock_connection):
127133

128134
# Search
129135

136+
130137
def test_search_success(client, mock_connection):
131138
mock_connection.call.return_value = Mock(
132139
result_point_ids=[
@@ -167,7 +174,6 @@ def test_search_invalid_vector(client):
167174
)
168175

169176

170-
171177
def test_batch_search_accepts_ef(client, mock_connection):
172178
mock_connection.call.return_value = Mock(results=[])
173179

@@ -182,8 +188,10 @@ def test_batch_search_accepts_ef(client, mock_connection):
182188
request = mock_connection.call.call_args.args[1]
183189
assert [query.ef for query in request.queries] == [256, 256]
184190

191+
185192
# Batch Search
186193

194+
187195
def test_batch_search_full_tuple(client, mock_connection):
188196
mock_connection.call.return_value = Mock(
189197
results=[
@@ -198,6 +206,7 @@ def test_batch_search_full_tuple(client, mock_connection):
198206
result = client.batch_search(queries=queries)
199207
assert result == [["p1"], ["p2"]]
200208

209+
201210
def test_batch_search_vectors_with_global_params(client, mock_connection):
202211
mock_connection.call.return_value = Mock(
203212
results=[
@@ -212,6 +221,7 @@ def test_batch_search_vectors_with_global_params(client, mock_connection):
212221
)
213222
assert result == [["p1"]]
214223

224+
215225
def test_batch_search_vector_similarity_with_global_limit(client, mock_connection):
216226
mock_connection.call.return_value = Mock(
217227
results=[
@@ -227,6 +237,7 @@ def test_batch_search_vector_similarity_with_global_limit(client, mock_connectio
227237
)
228238
assert result == [["p1"]]
229239

240+
230241
def test_batch_search_searchquery_objects(client, mock_connection):
231242
mock_connection.call.return_value = Mock(
232243
results=[
@@ -239,29 +250,35 @@ def test_batch_search_searchquery_objects(client, mock_connection):
239250
result = client.batch_search(queries=queries)
240251
assert result == [["p1"]]
241252

253+
242254
def test_batch_search_missing_globals_for_vector(client):
243255
queries = [DenseVector([1, 2, 3])]
244256
with pytest.raises(ValueError):
245257
client.batch_search(queries=queries)
246258

259+
247260
def test_batch_search_missing_limit(client):
248261
queries = [
249262
(DenseVector([1, 2, 3]), Similarity.COSINE),
250263
]
251264
with pytest.raises(ValueError):
252265
client.batch_search(queries=queries)
253266

267+
254268
def test_batch_search_invalid_format(client):
255269
queries = ["invalid"]
256270
with pytest.raises(TypeError):
257271
client.batch_search(queries=queries)
258272

273+
259274
# Close
260275

276+
261277
def test_close_closes_connection(client, mock_connection):
262278
client.close()
263279
mock_connection.close.assert_called_once()
264280

281+
265282
def test_context_manager_closes_connection(monkeypatch):
266283
conn = Mock(spec=GRPCConnection)
267284
monkeypatch.setattr("vortexdb.client.GRPCConnection", lambda _: conn)

‎client/python/tests/test_config.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def clean_env(monkeypatch):
1616

1717
# Checking from_env
1818

19+
1920
def test_config_requires_api_key(clean_env):
2021
with pytest.raises(ConfigurationError):
2122
VortexDBConfig.from_env()
@@ -32,8 +33,10 @@ def test_config_from_explicit_args(clean_env):
3233
assert cfg.api_key == "secret"
3334
assert cfg.timeout == 10.0
3435

36+
3537
# Env vars fallback
3638

39+
3740
def test_config_from_env_vars(clean_env, monkeypatch):
3841
monkeypatch.setenv("VORTEXDB_GRPC_URL", "127.0.0.1:1234")
3942
monkeypatch.setenv("VORTEXDB_API_KEY", "env-secret")
@@ -48,6 +51,7 @@ def test_config_from_env_vars(clean_env, monkeypatch):
4851

4952
# Defaults
5053

54+
5155
def test_config_default_grpc_url(clean_env, monkeypatch):
5256
monkeypatch.setenv("VORTEXDB_API_KEY", "secret")
5357

@@ -66,6 +70,7 @@ def test_config_default_timeout(clean_env, monkeypatch):
6670

6771
# Invalid Timeout
6872

73+
6974
def test_config_invalid_timeout(clean_env, monkeypatch):
7075
monkeypatch.setenv("VORTEXDB_API_KEY", "secret")
7176
monkeypatch.setenv("VORTEXDB_TIMEOUT", "not-a-number")

0 commit comments

Comments
 (0)