Skip to content

new: convert cluster operations to grpc#1116

Merged
joein merged 4 commits into
devfrom
convert-cluster-operations
Nov 20, 2025
Merged

new: convert cluster operations to grpc#1116
joein merged 4 commits into
devfrom
convert-cluster-operations

Conversation

@joein

@joein joein commented Nov 17, 2025

Copy link
Copy Markdown
Member

No description provided.

@netlify

netlify Bot commented Nov 17, 2025

Copy link
Copy Markdown

Deploy Preview for poetic-froyo-8baba7 ready!

Name Link
🔨 Latest commit 5e82573
🔍 Latest deploy log https://app.netlify.com/projects/poetic-froyo-8baba7/deploys/691b6da2e990f600089f5e11
😎 Deploy Preview https://deploy-preview-1116--poetic-froyo-8baba7.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@joein joein requested a review from tbung November 17, 2025 18:10
@coderabbitai

coderabbitai Bot commented Nov 17, 2025

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds bidirectional conversion between gRPC and REST representations for cluster-level operations and updates synchronous and asynchronous remote clients to use these conversions when gRPC is preferred. For gRPC calls the clients convert incoming cluster operations to gRPC messages and populate the corresponding field on UpdateCollectionClusterSetupRequest (move_shard, replicate_shard, abort_transfer, drop_replica, create_shard_key, delete_shard_key, restart_transfer, replicate_points). REST code paths remain unchanged. New test fixtures and a parameterized test cover both prefer_grpc options.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Numerous new, repetitive conversion methods (bidirectional) — moderate volume but consistent patterns.
  • Dispatch logic added in two client files (sync + async) — verify correct field mapping and timeout propagation.
  • Tests and fixtures expanded to cover many operation variants.

Areas needing extra attention:

  • Exact mapping of each cluster operation type to gRPC request fields in qdrant_client/qdrant_remote.py and qdrant_client/async_qdrant_remote.py
  • Round-trip correctness and enum/field mapping in qdrant_client/conversions/conversion.py
  • New fixtures and parametrized test behavior in tests/conversions/fixtures.py and tests/test_qdrant_client.py
  • Error handling for unknown/unsupported operation types.

Possibly related PRs

  • new: expose cluster operations #1114: Modifies client-side cluster_collection_update conversion and dispatch logic for cluster operations — strongly related to the same code paths.
  • new: update grpc #1113: Introduces ReplicatePoints and UpdateCollectionClusterSetup gRPC/protobuf changes that this PR depends on.

Suggested reviewers

  • generall

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess relevance to the changeset. Add a description explaining the purpose of converting cluster operations to gRPC, the operations affected, and any notable implementation details.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'new: convert cluster operations to grpc' accurately reflects the main change: adding gRPC conversion support for cluster operations across the codebase.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch convert-cluster-operations

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6d6e5a and 5e82573.

📒 Files selected for processing (3)
  • qdrant_client/async_qdrant_remote.py (1 hunks)
  • qdrant_client/conversions/conversion.py (3 hunks)
  • qdrant_client/qdrant_remote.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
qdrant_client/qdrant_remote.py (3)
qdrant_client/conversions/conversion.py (2)
  • convert_cluster_operations (2124-2171)
  • convert_cluster_operations (4549-4599)
qdrant_client/grpc/collections_pb2.pyi (9)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • UpdateCollectionClusterSetupRequest (2890-2942)
qdrant_client/grpc/collections_service_pb2_grpc.py (6)
  • CreateShardKey (175-181)
  • CreateShardKey (457-471)
  • DeleteShardKey (183-189)
  • DeleteShardKey (474-488)
  • UpdateCollectionClusterSetup (167-173)
  • UpdateCollectionClusterSetup (440-454)
qdrant_client/conversions/conversion.py (2)
qdrant_client/grpc/collections_pb2.pyi (24)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • move_shard (2906-2906)
  • replicate_shard (2908-2908)
  • abort_transfer (2910-2910)
  • drop_replica (2912-2912)
  • restart_transfer (2918-2918)
  • replicate_points (2920-2920)
  • shard_key (2530-2531)
  • shard_key (2560-2561)
  • shard_key (2614-2614)
  • shard_key (2842-2843)
  • shard_key (2878-2879)
  • placement (2849-2850)
  • filter (2801-2802)
  • from_shard_key (2795-2796)
  • to_shard_key (2798-2799)
  • ShardTransferMethod (330-330)
qdrant_client/http/models/models.py (18)
  • MoveShard (1666-1672)
  • ReplicateShard (2410-2416)
  • AbortShardTransfer (22-25)
  • Replica (2366-2368)
  • RestartTransfer (2447-2451)
  • ReplicatePoints (2400-2403)
  • MoveShardOperation (1675-1676)
  • ReplicateShardOperation (2419-2420)
  • AbortTransferOperation (28-29)
  • DropReplicaOperation (798-799)
  • DropShardingKeyOperation (806-807)
  • RestartTransferOperation (2454-2455)
  • ReplicatePointsOperation (2406-2407)
  • CreateShardingKey (559-576)
  • DropShardingKey (802-803)
  • ShardTransferMethod (2827-2838)
  • StartReshardingOperation (3056-3057)
  • AbortReshardingOperation (18-19)
qdrant_client/async_qdrant_remote.py (4)
qdrant_client/conversions/conversion.py (2)
  • convert_cluster_operations (2124-2171)
  • convert_cluster_operations (4549-4599)
qdrant_client/grpc/collections_pb2.pyi (9)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • UpdateCollectionClusterSetupRequest (2890-2942)
qdrant_client/http/models/models.py (6)
  • MoveShard (1666-1672)
  • ReplicateShard (2410-2416)
  • AbortShardTransfer (22-25)
  • Replica (2366-2368)
  • RestartTransfer (2447-2451)
  • ReplicatePoints (2400-2403)
qdrant_client/grpc/collections_service_pb2_grpc.py (6)
  • CreateShardKey (175-181)
  • CreateShardKey (457-471)
  • DeleteShardKey (183-189)
  • DeleteShardKey (474-488)
  • UpdateCollectionClusterSetup (167-173)
  • UpdateCollectionClusterSetup (440-454)
🪛 Ruff (0.14.5)
qdrant_client/qdrant_remote.py

2612-2612: Avoid specifying long messages outside the exception class

(TRY003)

qdrant_client/conversions/conversion.py

2109-2111: Avoid specifying long messages outside the exception class

(TRY003)


2171-2171: Avoid specifying long messages outside the exception class

(TRY003)


2191-2193: Avoid specifying long messages outside the exception class

(TRY003)


2208-2210: Avoid specifying long messages outside the exception class

(TRY003)


2236-2238: Avoid specifying long messages outside the exception class

(TRY003)


2270-2270: Avoid specifying long messages outside the exception class

(TRY003)


4594-4594: Prefer TypeError exception for invalid type

(TRY004)


4594-4594: Avoid specifying long messages outside the exception class

(TRY003)


4597-4597: Prefer TypeError exception for invalid type

(TRY004)


4597-4597: Avoid specifying long messages outside the exception class

(TRY003)


4599-4599: Avoid specifying long messages outside the exception class

(TRY003)


4692-4692: Avoid specifying long messages outside the exception class

(TRY003)

qdrant_client/async_qdrant_remote.py

2425-2425: Avoid specifying long messages outside the exception class

(TRY003)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Redirect rules - poetic-froyo-8baba7
  • GitHub Check: Header rules - poetic-froyo-8baba7
  • GitHub Check: Pages changed - poetic-froyo-8baba7
  • GitHub Check: Python 3.13.x on ubuntu-latest test
  • GitHub Check: Python 3.10.x on ubuntu-latest test
  • GitHub Check: Python 3.12.x on ubuntu-latest test
  • GitHub Check: Python 3.11.x on ubuntu-latest test
  • GitHub Check: Python 3.9.x on ubuntu-latest test
🔇 Additional comments (7)
qdrant_client/qdrant_remote.py (1)

2591-2619: LGTM! All previous critical issues have been addressed.

The gRPC implementation for cluster operations is now correct:

  • Field mapping matches the protobuf definition (drop_replica, not replica)
  • No duplicate conditions
  • Proper timeout handling and .result extraction
  • Complete coverage of all 8 cluster operation types

The static analysis hint about the exception message on line 2612 is a minor style suggestion that can optionally be addressed by defining a custom exception class, but this is not critical for functionality.

qdrant_client/async_qdrant_remote.py (1)

2405-2433: LGTM! Async implementation is correct.

The async version properly mirrors the sync implementation with all previous critical issues addressed:

  • Correct field names matching the protobuf definition
  • Proper async/await usage with timeout and .result extraction
  • Complete operation type coverage

The static analysis hint on line 2425 is the same minor style suggestion as in the sync version and is optional.

qdrant_client/conversions/conversion.py (5)

2123-2171: LGTM: Comprehensive cluster operation dispatcher.

The conversion method correctly handles all cluster operation types with appropriate type guards and a final ValueError for unsupported cases.


2189-2201: Appropriate defensive checks for internal-only fields.

The to_shard_id field guards are correct—these fields are for internal purposes and should never be converted to the REST representation. The HasField checks prevent accidental exposure of internal state through the API.

Also applies to: 2204-2213, 2234-2244


4548-4600: LGTM: Complete REST-to-gRPC dispatcher with appropriate guards.

The conversion method correctly handles all REST cluster operation types, explicitly rejects operations without gRPC counterparts (StartResharding, AbortResharding), and includes a final ValueError for invalid types.


4602-4666: Correct handling of internal field in REST-to-gRPC conversions.

All converters correctly set to_shard_id=None when constructing gRPC messages. This ensures the internal-only field is not inadvertently populated from external REST API calls.


4677-4692: LGTM: Consistent enum conversion in the reverse direction.

The convert_shard_transfer_method method properly converts REST enum values to their gRPC counterparts using fully qualified references throughout.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
qdrant_client/conversions/conversion.py (2)

2123-2270: Cluster op gRPC→REST conversions look correct; consider guarding MoveShard.to_shard_id as well

The new GrpcToRest.convert_cluster_operations and per-op converters (convert_move_shard, convert_replicate_shard, convert_abort_shard_transfer, convert_replica, convert_create_shard_key, convert_delete_shard_key, convert_restart_transfer, convert_replicate_points, convert_shard_transfer_method) are structurally sound and line up with the HTTP models and grpc stubs:

  • Field mappings (ids, peer ids, method, filter, shard keys, replica state) match the referenced model definitions.
  • Internal-only fields like to_shard_id are explicitly rejected for ReplicateShard, AbortShardTransfer, and RestartTransfer, which avoids silently losing information that has no REST representation.
  • Shard transfer method mapping is symmetric with the REST→gRPC converter.

The one inconsistency is convert_move_shard: it doesn’t guard against model.HasField("to_shard_id"), while the other cluster ops do. If core ever sets to_shard_id on a MoveShard, that information would be silently dropped on the REST side, unlike the explicit ValueError behavior for the other operations.

If you want consistent behavior across all cluster ops, you could add a similar guard:

     @classmethod
     def convert_move_shard(cls, model: grpc.MoveShard) -> rest.MoveShard:
+        if model.HasField("to_shard_id"):
+            raise ValueError(
+                "to_shard_id is a field for internal purposes, can't be converted to rest"
+            )  # pragma: no cover
         return rest.MoveShard(
             shard_id=model.shard_id,
             from_peer_id=model.from_peer_id,
             to_peer_id=model.to_peer_id,
             method=cls.convert_shard_transfer_method(model.method)
             if model.HasField("method")
             else None,
         )

This matches the defensive approach already used for ReplicateShard, AbortShardTransfer, and RestartTransfer.


2254-2270: ShardTransferMethod conversions are symmetric; minor stylistic nit only

The new convert_shard_transfer_method implementations in both directions correctly cover the four documented methods (stream_records, snapshot, wal_delta, resharding_stream_records) and are symmetric between GrpcToRest and RestToGrpc.

The only minor nit is the inconsistent style of referring to gRPC enums (grpc.StreamRecords / grpc.ReshardingStreamRecords vs grpc.ShardTransferMethod.Snapshot/WalDelta). That’s purely cosmetic and doesn’t affect behavior.

If you want to make this a bit clearer for future readers, you could normalize to the enum-qualified style everywhere (e.g. grpc.ShardTransferMethod.StreamRecords), but it’s not required.

Also applies to: 4675-4690

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 717640f and f78db74.

📒 Files selected for processing (5)
  • qdrant_client/async_qdrant_remote.py (1 hunks)
  • qdrant_client/conversions/conversion.py (3 hunks)
  • qdrant_client/qdrant_remote.py (1 hunks)
  • tests/conversions/fixtures.py (2 hunks)
  • tests/test_qdrant_client.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
tests/conversions/fixtures.py (2)
qdrant_client/grpc/collections_pb2.pyi (26)
  • move_shard (2906-2906)
  • MoveShard (2669-2697)
  • ShardTransferMethod (330-330)
  • replicate_shard (2908-2908)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • restart_transfer (2918-2918)
  • RestartTransfer (2759-2784)
  • replicate_points (2920-2920)
  • ReplicatePoints (2788-2812)
  • from_shard_key (2795-2796)
  • ShardKey (2495-2512)
  • to_shard_key (2798-2799)
  • filter (2801-2802)
  • Replica (2816-2829)
  • create_shard_key (2914-2914)
  • CreateShardKey (2833-2869)
  • shard_key (2530-2531)
  • shard_key (2560-2561)
  • shard_key (2614-2614)
  • shard_key (2842-2843)
  • shard_key (2878-2879)
  • placement (2849-2850)
  • ReplicaState (269-269)
  • delete_shard_key (2916-2916)
  • DeleteShardKey (2873-2886)
qdrant_client/http/models/models.py (9)
  • MoveShard (1666-1672)
  • ShardTransferMethod (2827-2838)
  • ReplicateShard (2410-2416)
  • AbortShardTransfer (22-25)
  • RestartTransfer (2447-2451)
  • ReplicatePoints (2400-2403)
  • Filter (914-924)
  • Replica (2366-2368)
  • ReplicaState (2380-2397)
qdrant_client/qdrant_remote.py (2)
qdrant_client/conversions/conversion.py (2)
  • convert_cluster_operations (2124-2171)
  • convert_cluster_operations (4549-4597)
qdrant_client/grpc/collections_pb2.pyi (9)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • UpdateCollectionClusterSetupRequest (2890-2942)
qdrant_client/async_qdrant_remote.py (3)
qdrant_client/conversions/conversion.py (2)
  • convert_cluster_operations (2124-2171)
  • convert_cluster_operations (4549-4597)
qdrant_client/grpc/collections_pb2.pyi (9)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • UpdateCollectionClusterSetupRequest (2890-2942)
qdrant_client/grpc/collections_service_pb2_grpc.py (6)
  • CreateShardKey (175-181)
  • CreateShardKey (457-471)
  • DeleteShardKey (183-189)
  • DeleteShardKey (474-488)
  • UpdateCollectionClusterSetup (167-173)
  • UpdateCollectionClusterSetup (440-454)
tests/test_qdrant_client.py (3)
qdrant_client/qdrant_client.py (1)
  • upsert (874-953)
qdrant_client/http/models/models.py (2)
  • ShardKeyWithFallback (2779-2781)
  • PointStruct (1985-1988)
qdrant_client/qdrant_remote.py (1)
  • upsert (1048-1138)
qdrant_client/conversions/conversion.py (2)
qdrant_client/grpc/collections_pb2.pyi (24)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • move_shard (2906-2906)
  • replicate_shard (2908-2908)
  • abort_transfer (2910-2910)
  • drop_replica (2912-2912)
  • restart_transfer (2918-2918)
  • replicate_points (2920-2920)
  • shard_key (2530-2531)
  • shard_key (2560-2561)
  • shard_key (2614-2614)
  • shard_key (2842-2843)
  • shard_key (2878-2879)
  • placement (2849-2850)
  • filter (2801-2802)
  • from_shard_key (2795-2796)
  • to_shard_key (2798-2799)
  • ShardTransferMethod (330-330)
qdrant_client/http/models/models.py (19)
  • MoveShard (1666-1672)
  • ReplicateShard (2410-2416)
  • AbortShardTransfer (22-25)
  • Replica (2366-2368)
  • RestartTransfer (2447-2451)
  • ReplicatePoints (2400-2403)
  • MoveShardOperation (1675-1676)
  • ReplicateShardOperation (2419-2420)
  • AbortTransferOperation (28-29)
  • DropReplicaOperation (798-799)
  • CreateShardingKeyOperation (579-580)
  • DropShardingKeyOperation (806-807)
  • RestartTransferOperation (2454-2455)
  • ReplicatePointsOperation (2406-2407)
  • CreateShardingKey (559-576)
  • DropShardingKey (802-803)
  • ShardTransferMethod (2827-2838)
  • StartReshardingOperation (3056-3057)
  • AbortReshardingOperation (18-19)
🪛 GitHub Actions: type-checkers
qdrant_client/conversions/conversion.py

[error] 4549-4549: Mypy error: Missing return statement at qdrant_client/conversions/conversion.py:4549. Command failed: 'poetry run mypy . --exclude "tools/async_client_generator" --disallow-incomplete-defs --disallow-untyped-defs' (exit code 1).

🪛 Ruff (0.14.5)
qdrant_client/qdrant_remote.py

2614-2614: Avoid specifying long messages outside the exception class

(TRY003)

qdrant_client/async_qdrant_remote.py

2427-2427: Avoid specifying long messages outside the exception class

(TRY003)

qdrant_client/conversions/conversion.py

2109-2111: Avoid specifying long messages outside the exception class

(TRY003)


2171-2171: Avoid specifying long messages outside the exception class

(TRY003)


2191-2193: Avoid specifying long messages outside the exception class

(TRY003)


2208-2210: Avoid specifying long messages outside the exception class

(TRY003)


2236-2238: Avoid specifying long messages outside the exception class

(TRY003)


2270-2270: Avoid specifying long messages outside the exception class

(TRY003)


4594-4594: Prefer TypeError exception for invalid type

(TRY004)


4594-4594: Avoid specifying long messages outside the exception class

(TRY003)


4597-4597: Prefer TypeError exception for invalid type

(TRY004)


4597-4597: Avoid specifying long messages outside the exception class

(TRY003)


4690-4690: Avoid specifying long messages outside the exception class

(TRY003)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Redirect rules - poetic-froyo-8baba7
  • GitHub Check: Header rules - poetic-froyo-8baba7
  • GitHub Check: Pages changed - poetic-froyo-8baba7
  • GitHub Check: Python 3.13.x on ubuntu-latest test
  • GitHub Check: Python 3.11.x on ubuntu-latest test
  • GitHub Check: Python 3.9.x on ubuntu-latest test
  • GitHub Check: Python 3.12.x on ubuntu-latest test
  • GitHub Check: Python 3.10.x on ubuntu-latest test
🔇 Additional comments (3)
tests/test_qdrant_client.py (1)

2267-2336: Cluster collection update test cleanly exercises both REST and gRPC paths

This parametrized test_cluster_collection_update does a nice job of covering the new cluster operations end‑to‑end:

  • Runs against both prefer_grpc=False and True, so it validates the new conversion paths in both directions.
  • Exercises creation of shard keys (including an initial ReplicaState.PARTIAL), upsert using ShardKeyWithFallback, a filtered ReplicatePointsOperation, and finally dropping a shard key.

The structure and version gating are consistent with the rest of this test module.

tests/conversions/fixtures.py (2)

1701-1732: Well-organized fixture mappings for cluster operations.

The dictionary structure effectively supports parameterized testing with:

  • A comprehensive "ClusterOperations" grouping for general conversion testing
  • Individual type-specific entries for targeted testing of each operation

This organization aligns well with the existing fixture patterns in the file.


1486-1486: No changes required — fixture design is intentional and correct.

The restart_transfer fixture at line 1486 is intentionally created without the method parameter as part of parametrized testing. This follows the established pattern used for similar cluster operations (move_shard and replicate_shard), which also provide two test variants each: one with an explicit method value and one relying on the proto3 default.

In proto3, all fields are implicitly optional, and unset enum fields default to 0 (the first enum value, StreamRecords). The conversion functions handle this correctly by directly accessing model.method without checks, allowing the implicit default to propagate. This design enables testing both explicit and default-value scenarios during REST↔gRPC conversions.

Comment thread qdrant_client/async_qdrant_remote.py Outdated
Comment thread qdrant_client/async_qdrant_remote.py Outdated
Comment thread qdrant_client/conversions/conversion.py
Comment thread qdrant_client/qdrant_remote.py Outdated
Comment thread qdrant_client/qdrant_remote.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
qdrant_client/conversions/conversion.py (1)

4548-4600: Past review concern resolved.

The previous review flagged that this method could fall through without returning for unknown ClusterOperations variants. This has been properly addressed with the addition of the final raise ValueError at line 4599, ensuring the function never returns None and provides a clear error for unsupported cases.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f78db74 and a6d6e5a.

📒 Files selected for processing (3)
  • qdrant_client/async_qdrant_remote.py (1 hunks)
  • qdrant_client/conversions/conversion.py (3 hunks)
  • qdrant_client/qdrant_remote.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
qdrant_client/qdrant_remote.py (3)
qdrant_client/conversions/conversion.py (2)
  • convert_cluster_operations (2124-2171)
  • convert_cluster_operations (4549-4599)
qdrant_client/grpc/collections_pb2.pyi (9)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • UpdateCollectionClusterSetupRequest (2890-2942)
qdrant_client/grpc/collections_service_pb2_grpc.py (6)
  • CreateShardKey (175-181)
  • CreateShardKey (457-471)
  • DeleteShardKey (183-189)
  • DeleteShardKey (474-488)
  • UpdateCollectionClusterSetup (167-173)
  • UpdateCollectionClusterSetup (440-454)
qdrant_client/async_qdrant_remote.py (2)
qdrant_client/conversions/conversion.py (2)
  • convert_cluster_operations (2124-2171)
  • convert_cluster_operations (4549-4599)
qdrant_client/grpc/collections_pb2.pyi (9)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • UpdateCollectionClusterSetupRequest (2890-2942)
qdrant_client/conversions/conversion.py (2)
qdrant_client/grpc/collections_pb2.pyi (24)
  • MoveShard (2669-2697)
  • ReplicateShard (2701-2729)
  • AbortShardTransfer (2733-2755)
  • Replica (2816-2829)
  • CreateShardKey (2833-2869)
  • DeleteShardKey (2873-2886)
  • RestartTransfer (2759-2784)
  • ReplicatePoints (2788-2812)
  • move_shard (2906-2906)
  • replicate_shard (2908-2908)
  • abort_transfer (2910-2910)
  • drop_replica (2912-2912)
  • restart_transfer (2918-2918)
  • replicate_points (2920-2920)
  • shard_key (2530-2531)
  • shard_key (2560-2561)
  • shard_key (2614-2614)
  • shard_key (2842-2843)
  • shard_key (2878-2879)
  • placement (2849-2850)
  • filter (2801-2802)
  • from_shard_key (2795-2796)
  • to_shard_key (2798-2799)
  • ShardTransferMethod (330-330)
qdrant_client/http/models/models.py (19)
  • MoveShard (1666-1672)
  • ReplicateShard (2410-2416)
  • AbortShardTransfer (22-25)
  • Replica (2366-2368)
  • RestartTransfer (2447-2451)
  • ReplicatePoints (2400-2403)
  • MoveShardOperation (1675-1676)
  • ReplicateShardOperation (2419-2420)
  • AbortTransferOperation (28-29)
  • DropReplicaOperation (798-799)
  • CreateShardingKeyOperation (579-580)
  • DropShardingKeyOperation (806-807)
  • RestartTransferOperation (2454-2455)
  • ReplicatePointsOperation (2406-2407)
  • CreateShardingKey (559-576)
  • DropShardingKey (802-803)
  • ShardTransferMethod (2827-2838)
  • StartReshardingOperation (3056-3057)
  • AbortReshardingOperation (18-19)
🪛 Ruff (0.14.5)
qdrant_client/qdrant_remote.py

2612-2612: Avoid specifying long messages outside the exception class

(TRY003)

qdrant_client/async_qdrant_remote.py

2425-2425: Avoid specifying long messages outside the exception class

(TRY003)

qdrant_client/conversions/conversion.py

2109-2111: Avoid specifying long messages outside the exception class

(TRY003)


2171-2171: Avoid specifying long messages outside the exception class

(TRY003)


2191-2193: Avoid specifying long messages outside the exception class

(TRY003)


2208-2210: Avoid specifying long messages outside the exception class

(TRY003)


2236-2238: Avoid specifying long messages outside the exception class

(TRY003)


2270-2270: Avoid specifying long messages outside the exception class

(TRY003)


4594-4594: Prefer TypeError exception for invalid type

(TRY004)


4594-4594: Avoid specifying long messages outside the exception class

(TRY003)


4597-4597: Prefer TypeError exception for invalid type

(TRY004)


4597-4597: Avoid specifying long messages outside the exception class

(TRY003)


4599-4599: Avoid specifying long messages outside the exception class

(TRY003)


4692-4692: Avoid specifying long messages outside the exception class

(TRY003)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Redirect rules - poetic-froyo-8baba7
  • GitHub Check: Header rules - poetic-froyo-8baba7
  • GitHub Check: Pages changed - poetic-froyo-8baba7
  • GitHub Check: Python 3.11.x on ubuntu-latest test
  • GitHub Check: Python 3.10.x on ubuntu-latest test
  • GitHub Check: Python 3.13.x on ubuntu-latest test
  • GitHub Check: Python 3.12.x on ubuntu-latest test
  • GitHub Check: Python 3.9.x on ubuntu-latest test

Comment thread qdrant_client/async_qdrant_remote.py Outdated
Comment thread qdrant_client/conversions/conversion.py
Comment thread qdrant_client/qdrant_remote.py Outdated

@tbung tbung left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bunch of this code could probably benefit from match statements when we drop 3.9, some of it might be slightly faster as look up tables (I didn't check what is and isn't hashable tho, so this might not work)

These are just some ideas/nits, nothing that needs to be addressed.

Comment on lines +2258 to +2268
if model == grpc.ShardTransferMethod.StreamRecords:
return rest.ShardTransferMethod.STREAM_RECORDS

if model == grpc.ShardTransferMethod.Snapshot:
return rest.ShardTransferMethod.SNAPSHOT

if model == grpc.ShardTransferMethod.WalDelta:
return rest.ShardTransferMethod.WAL_DELTA

if model == grpc.ShardTransferMethod.ReshardingStreamRecords:
return rest.ShardTransferMethod.RESHARDING_STREAM_RECORDS

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Could stuff like this not be a look up table?

Comment on lines +4561 to +4597
if isinstance(model, rest.MoveShardOperation):
operation = model.move_shard
return cls.convert_move_shard(operation)

if isinstance(model, rest.ReplicateShardOperation):
operation = model.replicate_shard
return cls.convert_replicate_shard(operation)

if isinstance(model, rest.AbortTransferOperation):
operation = model.abort_transfer
return cls.convert_abort_shard_transfer(operation)

if isinstance(model, rest.DropReplicaOperation):
operation = model.drop_replica
return cls.convert_replica(operation)

if isinstance(model, rest.CreateShardingKeyOperation):
operation = model.create_sharding_key
return cls.convert_create_shard_key(operation)

if isinstance(model, rest.DropShardingKeyOperation):
operation = model.drop_sharding_key
return cls.convert_delete_shard_key(operation)

if isinstance(model, rest.RestartTransferOperation):
operation = model.restart_transfer
return cls.convert_restart_transfer(operation)

if isinstance(model, rest.ReplicatePointsOperation):
operation = model.replicate_points
return cls.convert_replicate_points(operation)

if isinstance(model, rest.StartReshardingOperation): # pragma: no cover
raise ValueError("StartReshardingOperation has no grpc counterpart")

if isinstance(model, rest.AbortReshardingOperation): # pragma: no cover
raise ValueError("AbortReshardingOperation has not grpc counterpart")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If not look up table, this is probably nicer as a match statement once we drop 3.9

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can update it later, yes

@joein joein merged commit 9ce7346 into dev Nov 20, 2025
14 checks passed
joein added a commit that referenced this pull request Nov 24, 2025
* new: convert cluster operations to grpc

* fix: rollback coverage html

* fix: address ai comments

* fix: address review comments
@coderabbitai coderabbitai Bot mentioned this pull request Dec 2, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Feb 19, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants