mirror of
https://github.com/qdrant/qdrant-client.git
synced 2026-09-25 15:37:53 -05:00
Align with the latest public-api collections.proto: paginated ListCollections (limit/offset_token/next_offset_token) plus keyword prefix and text analysis fields (stopwords, stemmer, ascii_folding).
100 lines
3.6 KiB
Python
100 lines
3.6 KiB
Python
import inspect
|
|
|
|
from qdrant_client.serverless.models import (
|
|
CollectionConfig,
|
|
DenseVectorConfig,
|
|
Distance,
|
|
IntegerIndex,
|
|
KeywordIndex,
|
|
KeywordPrefixParams,
|
|
PrecisionTier,
|
|
SnowballParams,
|
|
SparseVectorConfig,
|
|
StemmingAlgorithm,
|
|
StopwordsSet,
|
|
TextIndex,
|
|
TokenizerType,
|
|
)
|
|
from qdrant_client.serverless import AsyncQdrantServerless, QdrantServerless
|
|
from qdrant_client.serverless.conversions import (
|
|
collection_config_from_grpc,
|
|
collection_config_to_grpc,
|
|
)
|
|
|
|
|
|
def test_collection_config_grpc_roundtrip() -> None:
|
|
config = CollectionConfig(
|
|
dense_vectors={
|
|
"": DenseVectorConfig(size=1536, distance=Distance.COSINE),
|
|
"colbert": DenseVectorConfig(
|
|
size=128,
|
|
distance=Distance.DOT,
|
|
multivector=True,
|
|
precision_tier=PrecisionTier.LOW,
|
|
),
|
|
},
|
|
sparse_vectors={"bm25": SparseVectorConfig(use_idf=True)},
|
|
payload_indexes={
|
|
"user_id": KeywordIndex(prefix=KeywordPrefixParams()),
|
|
"age": IntegerIndex(lookup=True, range=False),
|
|
"description": TextIndex(
|
|
tokenizer=TokenizerType.WORD,
|
|
lowercase=False,
|
|
ascii_folding=True,
|
|
stopwords=StopwordsSet(languages=["english"]),
|
|
stemmer=StemmingAlgorithm(snowball=SnowballParams(language="english")),
|
|
),
|
|
},
|
|
)
|
|
assert collection_config_from_grpc(collection_config_to_grpc(config)) == config
|
|
|
|
|
|
def test_optional_fields_stay_unset() -> None:
|
|
config = CollectionConfig(
|
|
dense_vectors={"": DenseVectorConfig(size=4, distance=Distance.EUCLID)},
|
|
payload_indexes={
|
|
"age": IntegerIndex(),
|
|
"user_id": KeywordIndex(),
|
|
"text": TextIndex(),
|
|
},
|
|
)
|
|
grpc_config = collection_config_to_grpc(config)
|
|
assert not grpc_config.dense_vectors[""].HasField("precision_tier")
|
|
assert not grpc_config.payload_indexes["age"].integer.HasField("lookup")
|
|
assert not grpc_config.payload_indexes["user_id"].keyword.HasField("prefix")
|
|
assert not grpc_config.payload_indexes["text"].text.HasField("tokenizer")
|
|
assert not grpc_config.payload_indexes["text"].text.HasField("ascii_folding")
|
|
assert not grpc_config.payload_indexes["text"].text.HasField("stopwords")
|
|
assert not grpc_config.payload_indexes["text"].text.HasField("stemmer")
|
|
assert collection_config_from_grpc(grpc_config) == config
|
|
|
|
|
|
def test_client_construction_is_offline() -> None:
|
|
client = QdrantServerless(url="https://serverless.example.qdrant.io", api_key="secret")
|
|
assert ("api-key", "secret") in client._remote._grpc_headers
|
|
assert client._remote._grpc_port == 443
|
|
assert client._remote._https
|
|
client.close()
|
|
|
|
|
|
def test_async_client_mirrors_sync_client() -> None:
|
|
sync_methods = {
|
|
name
|
|
for name, _ in inspect.getmembers(QdrantServerless, predicate=inspect.isfunction)
|
|
if not name.startswith("__")
|
|
}
|
|
async_methods = {
|
|
name
|
|
for name, _ in inspect.getmembers(AsyncQdrantServerless, predicate=inspect.isfunction)
|
|
if not name.startswith("__")
|
|
}
|
|
assert sync_methods == async_methods
|
|
for name in async_methods:
|
|
if name.startswith("_"):
|
|
continue
|
|
assert inspect.iscoroutinefunction(getattr(AsyncQdrantServerless, name)), name
|
|
|
|
client = AsyncQdrantServerless(url="https://serverless.example.qdrant.io", api_key="secret")
|
|
assert ("api-key", "secret") in client._remote._grpc_headers
|
|
assert client._remote._grpc_port == 443
|