Skip to content

Add asyncio-compatible API & first-class support for ydb-python-sdk objects (e.g. shared ydb.aio.QuerySessionPool) #20

@vladkolotvin

Description

@vladkolotvin

Title
Add asyncio-compatible API & first-class support for ydb-python-sdk objects (e.g. shared ydb.aio.QuerySessionPool)


What problem are you trying to solve?

langchain-ydb is great for quick PoC work, but in production RAG pipelines we usually:

  • run inside an async web-framework (FastAPI, Starlette, etc.);
  • reuse one global ydb.aio.Driver + QuerySessionPool across many components to avoid opening a new gRPC channel for every request.

Today the package exposes only the synchronous YDB VectorStore and instantiates its own internal driver/session pool (see the sync-only example in the README) (GitHub).
Meanwhile the official SDK already ships fully-featured asyncio primitives (ydb.aio.Driver, ydb.aio.QuerySessionPool, async execute_with_retries, …) (YDB).

This mismatch means:

  • We must wrap the sync VectorStore in run_in_executor, losing a lot of throughput.
  • Each LangChain call opens a new connection instead of borrowing one from our existing pool—hurting latency and exhausting connection limits.

Feature request

  1. Async variant of the VectorStore

    • Provide class AsyncYDB(VectorStore) or add async def aadd_texts, asearch, amaximal_marginal_relevance_search, etc. mirroring the standard LangChain async naming scheme (see PGVector / Chroma for precedent).
    • Ensure the async version can be registered via from_documents_async, as_retriever(…), etc.
  2. Pluggable SDK objects

    • Accept an already initialised ydb.Driver | ydb.aio.Driver or ydb.QuerySessionPool | ydb.aio.QuerySessionPool in the constructor, e.g.

      store = YDB(
          embeddings,
          config=settings,
          driver=my_driver,          # sync or async
          pool=my_query_pool,        # optional
      )
    • If nothing is supplied, fall back to the current behaviour for full backward compatibility.

  3. Graceful shutdown hooks
    When a user passes an external driver/pool the VectorStore should not close it; otherwise close the internally-created one on __del__ or async with.


Why it matters

Use-case Impact
FastAPI endpoint serving 100 req/s ~2-3× throughput gain by avoiding ThreadPoolExecutor
Worker running concurrent RAG tasks Lower memory footprint; predictable back-pressure
Serverless functions Faster cold-start because the global driver is reused

Possible implementation sketch

  • Copy the pattern used in langchain_community.vectorstores.pgvector.AsyncPGVector.
  • Factor out the SQL/YQL building logic into a helper shared by sync & async classes.
  • Gate import of ydb.aio behind if typing.TYPE_CHECKING or IS_ASYNC: to keep extra deps optional.

Additional context / links

  • YDB docs – async driver & pool examples (YDB)
  • Similar work in other integration packages (langchain-google-alloydb-pg, langchain-pgvector) that provide both sync and async flavours.

Happy to help with a PR if the approach sounds reasonable. Let me know what you think!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions