feat(client): support with and async with on the clients - #1347
feat(client): support with and async with on the clients#1347Aryan-Pardeshi wants to merge 1 commit into
with and async with on the clients#1347Conversation
…Client QdrantClient and AsyncQdrantClient own gRPC channels, an httpx client and, in local mode, a SQLite database plus a portalocker lockfile, but neither implemented the context manager protocol, so callers had to remember an explicit close() in a finally block. Adds __enter__/__exit__ to the sync client and __aenter__/__aexit__ to the async one. Both delegate to the existing idempotent close(). The async client is generated from the sync one, so the generator now takes a rename_methods map and rewrites __enter__/__exit__ into their async counterparts, forcing them async (they have no counterpart on AsyncQdrantBase) and remapping the string return annotation, which the name-based transformers do not touch. Closes qdrant#1285
✅ Deploy Preview for poetic-froyo-8baba7 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthrough
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The PR adds synchronous and asynchronous context-manager support so client resources are closed automatically, including when the block raises; no actionable merge-blocking risk remains after normal checks and review. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Closes #1285.
QdrantClientandAsyncQdrantClientown a gRPC channel, an httpx client and — in local mode — a SQLite database plus a portalocker lockfile, but neither implemented the context manager protocol. The cleanup path was thetry/finallyblock thatwithexists to remove.What's here
Sync (
qdrant_client/qdrant_client.py):Async (
qdrant_client/async_qdrant_client.py):Both
__exit__/__aexit__just delegate to the existingclose(), which is already idempotent on bothQdrantRemote(_closed = True) andQdrantLocal(_closed = Trueplus portalocker unlock), so a stray secondclose()after the block is still fine.The generator part
async_qdrant_client.pyis generated from the sync file, and the transform only convertsdef→async deffor names present onAsyncQdrantBase.__aenter__isn't there, so a naive transform would have emitted a sync__enter__on the async client — which Python'sasync withwon't accept.So
ClientGeneratornow takes arename_methodsmap (__enter__→__aenter__,__exit__→__aexit__) andClientFunctionDefTransformerhandles three things for those methods: renames them, forces them async regardless of theasync_methodslookup, and remaps the string return annotation ("QdrantClient"is anast.Constant, soNameTransformerandClassDefTransformerboth walk right past it).I ran the generator and diffed its output against the committed
async_qdrant_client.py: the context manager block comes out byte-identical, and the only other differences are pre-existing ones from my local tool versions (autoflake wasn't installed, and my ruff formatsfor (k, v) inwithout the parens).Tests
tests/test_context_manager.py, six cases across sync and async: the happy path, an exception raised inside the block (close still runs, exception still propagates), and a redundantclose()after the block to pin down the idempotence the design leans on. All use:memory:, so no server needed.Before the change the sync tests fail with
TypeError: 'QdrantClient' object does not support the context manager protocol (missed __exit__ method).Replaces #1329, which was branched from
masterand showed as conflicting against thedevbase this repo targets. Same change, clean history offdev.