How to fix asyncio RuntimeError: This event loop is already running

Problem

While trying to run an async def function using asyncio.run_until_complete(), e.g.

import asyncio
asyncio.get_event_loop().run_until_complete(asyncio.sleep(1))

you see an error message like

Cell In[3], line 15
     12           raise
     14 # Usage example:
---> 15 asyncio.get_event_loop().run_until_complete(asyncio.sleep(1))

File /usr/lib/python3.12/asyncio/base_events.py:663, in BaseEventLoop.run_until_complete(self, future)
    652 """Run until the Future is done.
    653 
    654 If the argument is a coroutine, it is wrapped in a Task.
   (...)
    660 Return the Future's result, or raise its exception.
    661 """
    662 self._check_closed()
--> 663 self._check_running()
    665 new_task = not futures.isfuture(future)
    666 future = tasks.ensure_future(future, loop=self)

File /usr/lib/python3.12/asyncio/base_events.py:622, in BaseEventLoop._check_running(self)
    620 def _check_running(self):
    621     if self.is_running():
--> 622         raise RuntimeError('This event loop is already running')
    623     if events._get_running_loop() is not None:
    624         raise RuntimeError(
    625             'Cannot run the event loop while another loop is running')

RuntimeError: This event loop is already running

Solution

Instead of using loop.run_until_complete(), use asyncio.create_task() to run the coroutine:

future = asyncio.get_event_loop().create_task(asyncio.sleep(1))

Optionally, you can await the future to wait for the coroutine to finish:

await future

The reason for this is that loop.run_until_complete() is meant for synchronous code and will always start the loop, hence it will fail if the loop is already running.

Typically, this error occurs if you are running code from a context like a Jupyter Notebook, which starts an event loop internally. You might need to change your code if you want to run it in another context such as a pure Python script.