run-llama / llama_index

LlamaIndex is a data framework for your LLM applications
https://docs.llamaindex.ai
MIT License
35.49k stars 5.01k forks source link

[Bug]: Neo4J PropertyGraphIndex.from_documents: RuntimeError: Event loop is closed #16033

Open yyoussef11 opened 3 days ago

yyoussef11 commented 3 days ago

Bug Description

I am using Neo4jPropertyGraphStore and then trying to create an index from the documents. (i got the same error even without using the from_documents) as i saw in other documentations as well (same error) Also note that i am using Ollama for Embeddings and for LLM

upon creating the index, i am facing the issue RuntimeError: Event loop is closed

To note that i have a big interest in Neo4jPropertyGraphStore and PropertyGraphIndex since i will be able to reuse the index from another file (or solution)

something like mentioned here:

index = PropertyGraphIndex.from_existing(
    property_graph_store=graph_store,
    llm=OpenAI(model="gpt-3.5-turbo", temperature=0.3),
    embed_model=OpenAIEmbedding(model_name="text-embedding-3-small"),
)

Version

llama-index==0.11.9

Steps to Reproduce

Ollama embeddings version: llama-index-embeddings-ollama==0.3.0 graph stores: llama-index-graph-stores-neo4j==0.3.2 llama index core: llama-index-core==0.11.9

Scenario 1: using PropertyGraphIndex from documents while using async = False (based on this https://github.com/run-llama/llama_index/issues/15292)

    index = PropertyGraphIndex.from_documents(
        documents= documents,
        use_async=False,
        property_graph_store=graph_store)

Got the error: sys:1: RuntimeWarning: coroutine 'SimpleLLMPathExtractor._aextract' was never awaited Note: looping over several directories failed, however i got documents from 1 directory for this one.

Scenario 2: using PropertyGraphIndex from documents with async = True (default) i received an error: AttributeError: 'NoneType' object has no attribute 'send'

Scenario 3: mentioning the kg_extractor:

    index = PropertyGraphIndex.from_documents(
        documents= documents,
        kg_extractor = ImplicitPathExtractor(),
        property_graph_store=graph_store)

Error: AttributeError: 'NoneType' object has no attribute 'send'

Relevant Logs/Tracbacks

Traceback (most recent call last):
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\runpy.py", line 198, in _run_module_as_main
    return _run_code(code, main_globals, None,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\runpy.py", line 88, in _run_code
    exec(code, run_globals)
  File "%USERPROFILE%\.vscode\extensions\ms-python.debugpy-2024.10.0-win32-x64\bundled\libs\debugpy\adapter/../..\debugpy\launcher/../..\debugpy\__main__.py", line 39, in <module>
    cli.main()
  File "%USERPROFILE%\.vscode\extensions\ms-python.debugpy-2024.10.0-win32-x64\bundled\libs\debugpy\adapter/../..\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 430, in main
    run()
  File "%USERPROFILE%\.vscode\extensions\ms-python.debugpy-2024.10.0-win32-x64\bundled\libs\debugpy\adapter/../..\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 284, in run_file
    runpy.run_path(target, run_name="__main__")
  File "%USERPROFILE%\.vscode\extensions\ms-python.debugpy-2024.10.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 321, in run_path
    return _run_module_code(code, init_globals, run_name,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\.vscode\extensions\ms-python.debugpy-2024.10.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 135, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "%USERPROFILE%\.vscode\extensions\ms-python.debugpy-2024.10.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 124, in _run_code
    exec(code, run_globals)
  File "D:\ISAI Code\IS AI\TripleH_POC\ingestGraphRag.py", line 67, in <module>
    index = PropertyGraphIndex.from_documents(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\core\indices\base.py", line 119, in from_documents
    return cls(
           ^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\core\indices\property_graph\base.py", line 134, in __init__
    super().__init__(
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\core\indices\base.py", line 77, in __init__   
    index_struct = self.build_index_from_nodes(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\core\indices\base.py", line 185, in build_index_from_nodes
    return self._build_index_from_nodes(nodes, **build_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\core\indices\property_graph\base.py", line 334, in _build_index_from_nodes
    nodes = self._insert_nodes(nodes or [])
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\core\indices\property_graph\base.py", line 274, in _insert_nodes
    kg_embeddings = asyncio.run(
                    ^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\core\instrumentation\dispatcher.py", line 297, in async_wrapper
    result = await func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\core\base\embeddings\base.py", line 407, in aget_text_embedding_batch
    nested_embeddings = await asyncio.gather(*embeddings_coroutines)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\embeddings\ollama\base.py", line 82, in _aget_text_embeddings
    return await asyncio.gather(
           ^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\llama_index\embeddings\ollama\base.py", line 95, in aget_general_text_embedding
    result = await self._async_client.embeddings(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\ollama\_client.py", line 701, in embeddings
    response = await self._request(
               ^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\ollama\_client.py", line 483, in _request
    response = await self._client.request(method, url, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_client.py", line 1585, in request
    return await self.send(request, auth=auth, follow_redirects=follow_redirects)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_client.py", line 1674, in send
    response = await self._send_handling_auth(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_client.py", line 1702, in _send_handling_auth      
    response = await self._send_handling_redirects(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_client.py", line 1739, in _send_handling_redirects 
    response = await self._send_single_request(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_client.py", line 1776, in _send_single_request     
    response = await transport.handle_async_request(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpx\_transports\default.py", line 377, in handle_async_request
    resp = await self._pool.handle_async_request(req)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpcore\_async\connection_pool.py", line 216, in handle_async_request
    raise exc from None
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpcore\_async\connection_pool.py", line 196, in handle_async_request
    response = await connection.handle_async_request(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpcore\_async\connection.py", line 101, in handle_async_request
    return await self._connection.handle_async_request(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpcore\_async\http11.py", line 142, in handle_async_request
    await self._response_closed()
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpcore\_async\http11.py", line 257, in _response_closed 
    await self.aclose()
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpcore\_async\http11.py", line 265, in aclose
    await self._network_stream.aclose()
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\httpcore\_backends\anyio.py", line 55, in aclose
    await self._stream.aclose()
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\site-packages\anyio\_backends\_asyncio.py", line 1202, in aclose        
    self._transport.close()
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\asyncio\proactor_events.py", line 109, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 795, in call_soon
    self._check_closed()
  File "%USERPROFILE%\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", line 541, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
dosubot[bot] commented 3 days ago

Hey @yyoussef11! 👋 I'm here to help you squash those bugs and answer your burning questions! Let's tackle this issue together and get things back on track.

To resolve the "RuntimeError: Event loop is closed" when creating an index using Neo4jPropertyGraphStore and PropertyGraphIndex in llama-index, ensure that the Neo4j connection is properly closed after the index creation. Here is the relevant code snippet:

from llama_index.core.indices.property_graph import PropertyGraphIndex
from llama_index.graph_stores.neo4j import Neo4jPropertyGraphStore

# Create a Neo4jPropertyGraphStore instance
graph_store = Neo4jPropertyGraphStore(
    username="neo4j",
    password="neo4j",
    url="bolt://localhost:7687",
    database="neo4j"
)

# Create the index
index = PropertyGraphIndex.from_documents(
    documents,
    property_graph_store=graph_store,
)

# Close the Neo4j connection explicitly
graph_store.close()

Ensure that you call graph_store.close() after creating the index to close the Neo4j connection explicitly. This should help in avoiding the "RuntimeError: Event loop is closed" error [1].

Additionally, when dealing with asynchronous operations, make sure to manage the event loop properly. Here are some best practices:

  1. Avoid Nested Event Loops: Ensure that asyncio.run is not called within an already running event loop. Check if an event loop is already running using asyncio.get_event_loop().is_running().

  2. Use await in Asynchronous Contexts: When inside an asynchronous function, use await instead of asyncio.run to avoid blocking the event loop.

  3. Graceful Shutdown: Ensure that all asynchronous tasks are properly awaited and completed before shutting down the event loop to avoid resource leaks.

  4. Error Handling: Implement proper error handling for asynchronous tasks to manage exceptions and ensure the stability of the application [2].

By following these steps, you should be able to mitigate the "RuntimeError: Event loop is closed" error and ensure smooth operation of your index creation process.

To continue talking to Dosu, mention @dosu.

logan-markewich commented 3 days ago

Usually "event look closed" means some other error happened

Try pip install -U llama-index-embeddings-ollama

Also test your embed model and llm on its own

print(llm.complete("hello"))
print(embed_model.get_text_embedding("hello"))
yyoussef11 commented 3 days ago

hello @logan-markewich thanks for the answer i was able to run the 2 prints, actually i am using ollama embeddings for a Redis vector store and it is perfectly working. Even when i used KnowledgeGraphIndex with Neo4jGraphStore i did not face issues with the embeddings. It was only when i moved to PropertyGraphIndex and Neo4jPropertyGraphStore that i started facing the mentioned issues.

yyoussef11 commented 3 days ago

To note that the suggestion of dosubot resulted in the same error. even after manually closing the connection to the graph_store, i still faced the issue.

FYI am using python 3.12

logan-markewich commented 3 days ago

Did you update your ollama embeddings though?

yyoussef11 commented 3 days ago

@logan-markewich yes, i have the latest ollama embeddings: llama-index-embeddings-ollama==0.3.0 i have started from a fresh environment with a new python and new llama index packages.