Skip to content

feat(client): add get_alias_names() shortcut method to all 6 client classes - #1307

Closed
Harsh23Kashyap wants to merge 1 commit into
qdrant:devfrom
Harsh23Kashyap:feat/client-contains-dunder
Closed

feat(client): add get_alias_names() shortcut method to all 6 client classes#1307
Harsh23Kashyap wants to merge 1 commit into
qdrant:devfrom
Harsh23Kashyap:feat/client-contains-dunder

Conversation

@Harsh23Kashyap

Copy link
Copy Markdown

Summary

Add a public get_alias_names() -> list[str] method to all 6 client classes. The current workaround is a list comprehension over the existing get_aliases().aliases. The new method is the obvious one-liner shortcut for "I just want the alias names".

Sibling of #1302 (get_collection_names()). Same regen-aware shape, but a different model and a different call site.

Fixes #1306

Changes

  • qdrant_client/qdrant_client.py — facade sync method that delegates to the inner client
  • qdrant_client/async_qdrant_client.py — facade async method that uses inspect.iscoroutine to handle both sync (local) and async (remote) inner clients
  • qdrant_client/qdrant_remote.py — remote sync method, return [a.alias_name for a in self.get_aliases().aliases]
  • qdrant_client/async_qdrant_remote.py — remote async method, return [a.alias_name for a in (await self.get_aliases()).aliases]
  • qdrant_client/local/qdrant_local.py — local sync method, reads self.aliases.keys() directly (no get_aliases() round-trip, no CollectionsAliasesResponse model)
  • qdrant_client/local/async_qdrant_local.py — local async method (kept as sync def since no I/O; the local transformer preserves it as sync)
  • tools/async_client_generator/client_generator.pyget_alias_names added to exclude_methods
  • tools/async_client_generator/remote_generator.pyget_alias_names added to exclude_methods
  • tools/generate_async_client.sh — AST-based post-regen sed step re-injects async def get_alias_names into async_qdrant_client.py and async_qdrant_remote.py. Also adds import inspect to the facade (the remote method doesn't use it, so no spurious import). Fails loudly with non-zero exit if close() cannot be found.
  • tests/test_get_alias_names.py — 14 new tests: sync + async × in-memory / path / remote × empty / after-create-alias × list-not-model, plus local-direct-access verification (no get_aliases() round-trip in local mode) and closed-state tests

Behavior

client = QdrantClient(":memory:")
client.get_alias_names()  # -> []

client.create_collection("a", vectors_config=...)
client.update_collection_aliases(change_aliases_operations=[
    CreateAliasOperation(create_alias=CreateAlias(alias_name="alias_for_a", collection_name="a"))
])
client.get_alias_names()  # -> ['alias_for_a']

Async equivalent (the async facade method is async and must be awaited):

client = AsyncQdrantClient(":memory:")
names = await client.get_alias_names()  # -> []

Remote mode delegates to the existing get_aliases() call. Local mode reads self.aliases.keys() directly — no intermediate CollectionsAliasesResponse model, no round-trip through the public get_aliases() API.

Verification

  • .ossvenv/bin/python -m pytest tests/test_get_alias_names.py -v — 14/14 pass
  • .ossvenv/bin/python -m ruff check on the 9 changed source files — clean (the 3 pre-existing F541 errors on master/dev are in the __init__ of the remote classes, not in my added code)
  • .ossvenv/bin/python -m ruff format --check --line-length 99 on the changed files — clean
  • .ossvenv/bin/python -m mypy on the 6 source files — clean
  • bash tools/generate_async_client.sh end-to-end with the new sed step: async def get_alias_names is correctly re-injected into async_qdrant_client.py and async_qdrant_remote.py, and import inspect is added to the facade (idempotent). Re-running the sed step is a no-op.

Notes

… classes

`QdrantClient`, `AsyncQdrantClient`, `QdrantRemote`, `AsyncQdrantRemote`,
`QdrantLocal`, and `AsyncQdrantLocal` all gain a public
`get_alias_names()` method that returns a `list[str]` of all alias
names.

The common case -- 'I just want the alias names' -- currently requires
`[a.alias_name for a in client.get_aliases().aliases]`. The new
method is a one-liner shortcut.

- Remote mode: delegates to `get_aliases()` and extracts `.alias_name`
  from each `AliasDescription`. No new network round-trip.
- Local mode: reads `self.aliases.keys()` directly. No
  intermediate `CollectionsAliasesResponse` model construction.
- The async facade uses `inspect.iscoroutine` to handle both the
  sync (local) and async (remote) inner clients.

Sibling of #1302 (`get_collection_names`). Same regen-aware shape:
`generate_async_client.sh` has an AST-based post-regen step that
re-injects `async def get_alias_names` into the facade and remote
async files. The facade's injected method uses `inspect.iscoroutine`,
so the sed step also adds `import inspect` at the top of the facade
(idempotent: skips if already present).

`AsyncQdrantLocal.get_alias_names` stays a sync `def` (no I/O),
kept as sync by the local transformer without intervention.

Fixes #1306
@netlify

netlify Bot commented Aug 2, 2026

Copy link
Copy Markdown

Deploy Preview for poetic-froyo-8baba7 ready!

Name Link
🔨 Latest commit 13eef10
🔍 Latest deploy log https://app.netlify.com/projects/poetic-froyo-8baba7/deploys/6a6f0e0e9a713e00097ca195
😎 Deploy Preview https://deploy-preview-1307--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.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds get_alias_names() to all synchronous and asynchronous client variants. Local clients return alias dictionary keys after closed-client validation. Remote clients extract alias_name values from get_aliases(). The asynchronous facade handles both coroutine and synchronous underlying implementations. Async client generators exclude the custom methods and reinject them after generation. Tests cover local, remote, path-based, asynchronous, empty, populated, and closed-client cases.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: joein, generall

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the addition of get_alias_names() to all six client classes.
Description check ✅ Passed The description directly explains the new method, implementation details, tests, and regeneration support.
Linked Issues check ✅ Passed The changes satisfy the primary get_alias_names() requirements across local, remote, synchronous, and asynchronous clients [#1306].
Out of Scope Changes check ✅ Passed The code, tests, and generator updates are directly related to the linked issue objectives [#1306].
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@qdrant_client/async_qdrant_client.py`:
- Line 12: Update AsyncQdrantBase to declare get_alias_names with overloads or a
signature that supports both synchronous and asynchronous implementations, so
callers using a statically typed AsyncQdrantBase can safely inspect and await
the result. Preserve AsyncQdrantRemote’s async behavior and AsyncQdrantLocal’s
sync behavior.

In `@qdrant_client/local/async_qdrant_local.py`:
- Around line 676-680: Update the closed-instance error in get_alias_names to
use the established “QdrantLocal instance is closed. Please create a new
instance.” wording, matching the other closed checks in the file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6979111d-4fec-4195-b446-2103ae9d525f

📥 Commits

Reviewing files that changed from the base of the PR and between 399449a and 13eef10.

📒 Files selected for processing (10)
  • qdrant_client/async_qdrant_client.py
  • qdrant_client/async_qdrant_remote.py
  • qdrant_client/local/async_qdrant_local.py
  • qdrant_client/local/qdrant_local.py
  • qdrant_client/qdrant_client.py
  • qdrant_client/qdrant_remote.py
  • tests/test_get_alias_names.py
  • tools/async_client_generator/client_generator.py
  • tools/async_client_generator/remote_generator.py
  • tools/generate_async_client.sh

#
# ****** WARNING: THIS FILE IS AUTOGENERATED ******

import inspect

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Inspect how get_alias_names is declared on the async base class(es).
rg -n -B2 -A5 'def get_alias_names' qdrant_client/async_client_base.py qdrant_client/client_base.py 2>/dev/null

Repository: qdrant/qdrant-client

Length of output: 158


🏁 Script executed:

#!/bin/bash
set -u

echo "Tracked files matching get_alias_names or async client base:"
git ls-files | rg '(^|/)(async_qdrant_client\.py|async_client_base\.py|.*client_base\.[pm]y)$' || true

echo
echo "Search get_alias_names across repository:"
rg -n -B3 -A6 'get_alias_names\s*[:=]' . || true

echo
echo "Search inspect.iscoroutine and alias names:"
rg -n -B3 -A6 'inspect\.iscoroutine|iscoroutine|AliasNames|alias_names' qdrant_client || true

echo
echo "List qdrant_client top files:"
find qdrant_client -maxdepth 2 -type f | sort

Repository: qdrant/qdrant-client

Length of output: 12681


🏁 Script executed:

#!/bin/bash
set -u

echo "Check async_qdrant_client around import and get_alias_names if present:"
wc -l qdrant_client/async_qdrant_client.py 2>/dev/null || true
sed -n '1,25p' qdrant_client/async_qdrant_client.py 2>/dev/null || true
sed -n '1480,1540p' qdrant_client/async_qdrant_client.py 2>/dev/null || true

echo
echo "Inspect base class files if present:"
for f in qdrant_client/async_client_base.py qdrant_client/client_base.py; do
  if [ -f "$f" ]; then
    echo "--- $f"
    wc -l "$f"
    rg -n -B2 -A8 'class .*Base|get_alias_names|alias_names' "$f" || true
  fi
done

echo
echo "Search for AsyncQdrantLocal/AsyncQdrantRemote definitions:"
rg -n -B2 -A10 'class AsyncQdrant(Local|Remote)|AsyncQdrantBase' qdrant_client || true

Repository: qdrant/qdrant-client

Length of output: 14118


🏁 Script executed:

#!/bin/bash
set -u

echo "AsyncQdrantBase alias-related methods:"
rg -n -B3 -A12 'get_alias_names|get_aliases|update_collection_aliases|get_collection_aliases' qdrant_client/async_client_base.py

echo
echo "AsyncQdrantLocal methods around alias methods and class inheritance:"
rg -n -B5 -A8 'get_alias_names|get_aliases|class AsyncQdrantLocal|AsyncQdrantBase|super\(' qdrant_client/local/async_qdrant_local.py

echo
echo "AsyncQdrantRemote methods around alias methods and class inheritance:"
rg -n -B5 -A8 'get_alias_names|get_aliases|class AsyncQdrantRemote|AsyncQdrantBase|super\(' qdrant_client/async_qdrant_remote.py

Repository: qdrant/qdrant-client

Length of output: 7545


Declare get_alias_names() in the async base before awaiting it.

AsyncQdrantBase does not define get_alias_names(), but AsyncQdrantRemote.get_alias_names() is async and AsyncQdrantLocal.get_alias_names() is sync. Add a base overloads/signature that covers both call forms, or change the local implementation so inspect.iscoroutine(result) and await result is not mypy-invisible when _client is statically typed as AsyncQdrantBase.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qdrant_client/async_qdrant_client.py` at line 12, Update AsyncQdrantBase to
declare get_alias_names with overloads or a signature that supports both
synchronous and asynchronous implementations, so callers using a statically
typed AsyncQdrantBase can safely inspect and await the result. Preserve
AsyncQdrantRemote’s async behavior and AsyncQdrantLocal’s sync behavior.

Comment on lines +676 to +680
def get_alias_names(self) -> list[str]:
if self.closed:
raise RuntimeError("AsyncQdrantLocal instance is closed. Please create a new instance.")
return list(self.aliases.keys())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Match the established "closed" error message wording in this file.

Every other closed-instance check in this file uses "QdrantLocal instance is closed. Please create a new instance." Line 678 uses "AsyncQdrantLocal instance is closed." instead. Use the same wording as the rest of the file for consistency.

✏️ Proposed fix
     def get_alias_names(self) -> list[str]:
         if self.closed:
-            raise RuntimeError("AsyncQdrantLocal instance is closed. Please create a new instance.")
+            raise RuntimeError("QdrantLocal instance is closed. Please create a new instance.")
         return list(self.aliases.keys())
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def get_alias_names(self) -> list[str]:
if self.closed:
raise RuntimeError("AsyncQdrantLocal instance is closed. Please create a new instance.")
return list(self.aliases.keys())
def get_alias_names(self) -> list[str]:
if self.closed:
raise RuntimeError("QdrantLocal instance is closed. Please create a new instance.")
return list(self.aliases.keys())
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qdrant_client/local/async_qdrant_local.py` around lines 676 - 680, Update the
closed-instance error in get_alias_names to use the established “QdrantLocal
instance is closed. Please create a new instance.” wording, matching the other
closed checks in the file.

@Harsh23Kashyap Harsh23Kashyap closed this by deleting the head repository Aug 2, 2026
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.

1 participant