qdrant-client
qdrant-client copied to clipboard
Pydantic missing field error on collection_cluster_info response
Hi, I'm getting a Pydantic missing field exception on the field obj.result.resharding_operations when using qdrant.http.cluster_api.collection_cluster_info(...).
When looking at the server source, it looks like currently this field doesn't get serialized if it's empty: https://github.com/qdrant/qdrant/blob/9fa86106e85d734765efe2c686a3ce975e53fb38/lib/collection/src/operations/types.rs#L210
Environment: qdrant-client: 1.11.1 qdrant: 1.11.3
Traceback:
Traceback (most recent call last):
File "/data/scripts/rebalance.py", line 10, in <module>
cluster_info = qdrant.http.cluster_api.collection_cluster_info(collection).result
File "/data/scripts/venv/lib64/python3.9/site-packages/qdrant_client/http/api/cluster_api.py", line 302, in collection_cluster_info
return self._build_for_collection_cluster_info(
File "/data/scripts/venv/lib64/python3.9/site-packages/qdrant_client/http/api/cluster_api.py", line 81, in _build_for_collection_cluster_info
return self.api_client.request(
File "/data/scripts/venv/lib64/python3.9/site-packages/qdrant_client/http/api_client.py", line 79, in request
return self.send(request, type_)
File "/data/scripts/venv/lib64/python3.9/site-packages/qdrant_client/http/api_client.py", line 101, in send
raise ResponseHandlingException(e)
qdrant_client.http.exceptions.ResponseHandlingException: 1 validation error for ParsingModel[InlineResponse2008] (for parse_as_type)
obj.result.resharding_operations
Field required [type=missing, input_value={'peer_id': 4660132199939..., 'shard_transfers': []}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.9/v/missing
Hi @ArthurMelin
Could you provide a minimal reproducible code snippet please? So we could confirm the problem and also see how you're using it
Sure, here it is:
from qdrant_client import QdrantClient
qdrant = QdrantClient()
peers = [int(p) for p in qdrant.http.cluster_api.cluster_status().result.peers]
collections = [c.name for c in qdrant.http.collections_api.get_collections().result.collections]
for collection in collections:
cluster_info = qdrant.http.cluster_api.collection_cluster_info(collection).result
shards = (
[{"id": s.shard_id, "peer": cluster_info.peer_id} for s in cluster_info.local_shards] +
[{"id": s.shard_id, "peer": s.peer_id} for s in cluster_info.remote_shards]
)
shards.sort(key=lambda s: s["id"])
peer_shards = {p: [s["id"] for s in shards if s["peer"] == p] for p in peers}
while True:
min_peer = min(peer_shards.keys(), key=lambda k: len(peer_shards[k]))
max_peer = max(peer_shards.keys(), key=lambda k: len(peer_shards[k]))
if len(peer_shards[max_peer]) - len(peer_shards[min_peer]) <= 1:
break
shard = peer_shards[max_peer][-1]
print(f"move shard {shard} from {max_peer} to {min_peer}")
peer_shards[max_peer].remove(shard)
peer_shards[min_peer].append(shard)
Hi @ArthurMelin It seems to be a bug in our openapi schema, which resulted in generating the incorrect model. Thanks for pointing it out
Should be fixed after releasing this one https://github.com/qdrant/qdrant/pull/5060
Hey @ArthurMelin
The fix should be available with the next release You can try it out now with the dev branch
Should be available as of qdrant-client v1.11.3 and qdrant v1.11.4