Skip to content

feat(retrievers): add async retriever support via neo4j.AsyncDriver (#406)#552

Open
1HazyOne707 wants to merge 1 commit into
neo4j:mainfrom
1HazyOne707:feat/async-retrievers-406
Open

feat(retrievers): add async retriever support via neo4j.AsyncDriver (#406)#552
1HazyOne707 wants to merge 1 commit into
neo4j:mainfrom
1HazyOne707:feat/async-retrievers-406

Conversation

@1HazyOne707

Copy link
Copy Markdown

Summary

Closes #406

Adds async variants of all core retrievers so users can use neo4j.AsyncDriver without maintaining two driver instances in parallel or spawning threads to avoid blocking the event loop.

Usage

import neo4j
from neo4j_graphrag.retrievers import AsyncVectorRetriever

driver = neo4j.AsyncGraphDatabase.driver(URI, auth=AUTH)
retriever = await AsyncVectorRetriever(driver, "my-index", embedder).async_init()
results = await retriever.search(query_text="Find me a book about Fremen", top_k=5)

Design

  • async_init() is a separate awaitable method (since __init__ cannot be async) that fetches index metadata from Neo4j — mirrors the sync retriever pattern where _fetch_index_infos() is called in __init__
  • All driver.execute_query() calls are replaced with await driver.execute_query()
  • AsyncText2CypherRetriever.async_init() fetches the Neo4j schema if not provided at construction time
  • Reuses all existing query-building logic, validation models, and error types — no duplication of business logic

Changes

src/neo4j_graphrag/types.py

  • AsyncNeo4jDriverModel — validates neo4j.AsyncDriver
  • AsyncVectorRetrieverModel, AsyncVectorCypherRetrieverModel, AsyncHybridRetrieverModel, AsyncHybridCypherRetrieverModel, AsyncText2CypherRetrieverModel

src/neo4j_graphrag/retrievers/base.py

  • AsyncRetriever ABC with async search(), async get_search_results(), async _fetch_index_infos()

New files

  • retrievers/async_vector.pyAsyncVectorRetriever, AsyncVectorCypherRetriever
  • retrievers/async_hybrid.pyAsyncHybridRetriever, AsyncHybridCypherRetriever
  • retrievers/async_text2cypher.pyAsyncText2CypherRetriever

retrievers/__init__.py

  • Exports all five async retriever classes

tests/unit/retrievers/test_async_vector.py

  • Init validation, async_init, search with vector, search with text, missing embedder, missing query, default formatter, AsyncVectorCypherRetriever

…eo4j#406)

Adds AsyncRetriever base class and async variants of all core retrievers,
allowing users to use neo4j.AsyncDriver without maintaining two driver
instances or spawning threads.

Changes:
- types.py: Add AsyncNeo4jDriverModel (validates neo4j.AsyncDriver) and
  async model variants for all retrievers
- retrievers/base.py: Add AsyncRetriever ABC with async search(),
  async get_search_results(), async _fetch_index_infos()
- retrievers/async_vector.py: AsyncVectorRetriever, AsyncVectorCypherRetriever
- retrievers/async_hybrid.py: AsyncHybridRetriever, AsyncHybridCypherRetriever
- retrievers/async_text2cypher.py: AsyncText2CypherRetriever
- retrievers/__init__.py: Export all async retriever classes

Usage:
    driver = neo4j.AsyncGraphDatabase.driver(URI, auth=AUTH)
    retriever = await AsyncVectorRetriever(driver, 'my-index').async_init()
    results = await retriever.search(query_text='find something', top_k=5)

Closes neo4j#406
@1HazyOne707 1HazyOne707 requested a review from a team as a code owner June 27, 2026 19:01
@1HazyOne707

Copy link
Copy Markdown
Author

Hi @stellasia — I've opened this PR to address #406. I also submitted the Neo4j CLA to cla@neo4j.com earlier today, so that should be processing.

Happy to make any adjustments based on your feedback — particularly around the async_init() pattern if there's a preferred approach for async construction in this codebase.

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.

Allow async driver in retrievers

1 participant