Files
qdrant-client/tests/fixtures/points.py
George a8beff7c96 Drop python3.9 (#1110)
* new: remove vectors_count, update http and grpc models

* fix: update inspection cache

* new: add conversions and update interface

* fix: fix some conversions

* fix: fix typo

* fix: fix isinstance

* fix: regen async

* fix: fix update_filter usage, fix isinstance

* tests: collection metadata test

* fix: address backward compatibility in test

* new: update models, add max payload index count and copy vectors

* fix; update _inspection_cache

* new: add read consistency to count points

* Allow uuids in interface (#1085)

* new: direct uuid support

* tests: add uuid tests

* fix: update inspection cache

* new: add collection metadata and tests to local mode (#1089)

* new: add collection metadata and tests to local mode

* fix: regen async client

* new: implement parametrized rrf in local mode (#1087)

* new: implement parametrized rrf in local mode

* refactoring: use a variable for a magic value

* fix: adjust conversion according to AI

* Update filter (#1090)

* new: add missing update_filter, implement it in local mode

* fix: fix type hint, fix update operation, fix rest uploader, add tests

* fix: fix update filter is None case

* fix: mypy was not a good boy

* Text any filter (#1091)

* new: add match text any local mode

* tests: add match text any tests

* new: update models, remove init_from and locks (#1100)

* new: update models, remove init_from and locks

* deprecate: remove init from tests

* deprecate: remove lock tests

* new: convert ascii_folding

* fix: fix type stub

* new: convert acorn

* new: convert shard key with fallback

* new: update grpcio and grpcio tools in generator (#1106)

* new: update grpcio and grpcio tools in generator

* fix: bind grpcio and tools versions to 1.62.0 in generator

* Remove deprecated methods (#1103)

* deprecate: remove old api methods

* deprecate: remove type stub for removed methods

* deprecate: remove old api methods from test_qdrant_client

* deprecate: replace search with query points in test_in_memory

* deprecate: replace search methods in fastembed mixin with query points

* deprecate: replace old api methods in test async qdrant client

* deprecate: replace search with query points in test delete points

* deprecate: replace discover and context with query points in test_discovery

* deprecate: replace recommend_groups with query_points_groups in test_group_recommend

* deprecate: replace search_groups in test_group_search

* deprecate: replace recommend with query points in test_recommendation

* deprecate: replace search with query points in test search

* deprecate: replace context and discover with query points in test sparse discovery

* deprecate: replace search with query points in test sparse idf search

* deprecate: replace recommend with query points in test sparse recommend

* deprecate: replace search with query points in test sparse search

* deprecate: replace missing search request with query request in qdrant_fastembed

* deprecate: replace search with query points in test multivector search queries

* deprecate: replace upload records with upload points in test_updates

* deprecate: remove redundant structs (#1104)

* deprecate: remove redundant structs

* fix: do not use removed conversions in local mode

* fix: remove redundant conversions, simplify types.QueryRequest

* deprecate: replace old style grpc vector conversion to a new one (#1105)

* deprecate: replace old style grpc vector conversion to a new one

* fix: ignore union attr in conversion

* review fixes

---------

Co-authored-by: generall <andrey@vasnetsov.com>

---------

Co-authored-by: generall <andrey@vasnetsov.com>

---------

Co-authored-by: generall <andrey@vasnetsov.com>

* new: deprecate add, query, query_batch in fastembed mixin (#1102)

* new: deprecate add, query, query_batch in fastembed mixin

* 1.16 -> 1.17

---------

Co-authored-by: generall <andrey@vasnetsov.com>

---------

Co-authored-by: generall <andrey@vasnetsov.com>

* new: yet another update

* new: add initial_state to create shard key (#1109)

* new: drop python3.9, replace union and optional with | where possible

* fix: fix missing type hints, regen async

* fix: remove redundant optional

* fix: fix ai comments

* fix: update type hints from merge

* new: update pyproject and lock

* new: replace optional and union with |

* new: remove optional and union from qdrant local

* new: replace union with | in client classes

* fix: replace remaining union, optional, etc, address review comments

* new: adjust numpy versioning

---------

Co-authored-by: generall <andrey@vasnetsov.com>
2025-12-05 16:32:24 +07:00

134 lines
4.4 KiB
Python

import random
import uuid
import numpy as np
from qdrant_client._pydantic_compat import construct
from qdrant_client.http import models
from qdrant_client.http.models import SparseVector
from qdrant_client.local.sparse import validate_sparse_vector
from tests.fixtures.payload import one_random_payload_please
def random_vectors(
vector_sizes: dict[str, int] | int,
) -> models.VectorStruct:
if isinstance(vector_sizes, int):
return np.random.random(vector_sizes).round(3).tolist()
elif isinstance(vector_sizes, dict):
vectors = {}
for vector_name, vector_size in vector_sizes.items():
vectors[vector_name] = np.random.random(vector_size).round(3).tolist()
return vectors
else:
raise ValueError("vector_sizes must be int or dict")
def random_multivectors(vector_sizes: dict[str, int] | int) -> models.VectorStruct:
if isinstance(vector_sizes, int):
vec_count = random.randint(1, 10)
return generate_random_multivector(vector_sizes, vec_count)
elif isinstance(vector_sizes, dict):
vectors = {}
for vector_name, vector_size in vector_sizes.items():
vec_count = random.randint(1, 10)
vectors[vector_name] = generate_random_multivector(vector_size, vec_count)
return vectors
else:
raise ValueError("vector_sizes must be int or dict")
def generate_random_multivector(vec_size: int, vec_count: int) -> list[list[float]]:
multivec = []
for _ in range(vec_count):
multivec.append(np.random.random(vec_size).round(3).tolist())
return multivec
# Generate random sparse vector with given size and density
# The density is the probability of non-zero value over the whole vector
def generate_random_sparse_vector(size: int, density: float) -> SparseVector:
num_non_zero = int(size * density)
indices: list[int] = random.sample(range(size), num_non_zero)
values: list[float] = [round(random.random(), 6) for _ in range(num_non_zero)]
sparse_vector = SparseVector(indices=indices, values=values)
validate_sparse_vector(sparse_vector)
return sparse_vector
def generate_random_sparse_vector_uneven(size: int, density: float) -> SparseVector:
if random.random() > 0.5:
size = int(size * 0.3)
return generate_random_sparse_vector(size, density)
def generate_random_sparse_vector_list(
num_vectors: int, vector_size: int, vector_density: float
) -> list[SparseVector]:
sparse_vector_list = []
for _ in range(num_vectors):
sparse_vector = generate_random_sparse_vector(vector_size, vector_density)
sparse_vector_list.append(sparse_vector)
return sparse_vector_list
def random_sparse_vectors(
vector_sizes: dict[str, int],
even: bool = True,
) -> models.VectorStruct:
vectors = {}
for vector_name, vector_size in vector_sizes.items():
# use sparse vectors with 20% density
if even:
vectors[vector_name] = generate_random_sparse_vector(vector_size, density=0.2)
else:
vectors[vector_name] = generate_random_sparse_vector_uneven(vector_size, density=0.2)
return vectors
def generate_points(
num_points: int,
vector_sizes: dict[str, int] | int,
with_payload: bool = False,
random_ids: bool = False,
skip_vectors: bool = False,
sparse: bool = False,
even_sparse: bool = True,
multivector: bool = False,
) -> list[models.PointStruct]:
if skip_vectors and isinstance(vector_sizes, int):
raise ValueError("skip_vectors is not supported for single vector")
points = []
for i in range(num_points):
payload = None
if with_payload:
payload = one_random_payload_please(i)
idx = i
if random_ids:
idx = str(uuid.uuid4())
if sparse:
vectors = random_sparse_vectors(vector_sizes, even=even_sparse)
elif multivector:
vectors = random_multivectors(vector_sizes)
else:
vectors = random_vectors(vector_sizes)
if skip_vectors:
if random.random() > 0.8:
vector_to_skip = random.choice(list(vectors.keys()))
vectors.pop(vector_to_skip)
points.append(
construct(
models.PointStruct,
id=idx,
vector=vectors,
payload=payload,
)
)
return points