25

I am trying to learn about asyncio for a websockets client. Every piece of code I try gets the following error:

RuntimeError: asyncio.run() cannot be called from a running event loop

I have tried the most simple code and it always gives that RuntimeError. I tried installing the full anaconda distribution again, etc, and can´t find what the problem might be.

I am using Spyder 3.3.3 with Python 3.7.3

An example of code that should work:

import asyncio

async def main():
    print('hello')
    await asyncio.sleep(1)
    print('world')

asyncio.run(main())

Error message:

File "C:\Users\jmart\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 786, in runfile
  execfile(filename, namespace)
File "C:\Users\jmart\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
  exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/jmart/Documents/asynk2.py", line 8, in <module>
  asyncio.run(main())
File "C:\Users\jmart\Anaconda3\lib\asyncio\runners.py", line 34, in run
  "asyncio.run() cannot be called from a running event loop")
RuntimeError: asyncio.run() cannot be called from a running event loop
4
  • 4
    Did you try to run the code form a terminal typing python3.7 asynk2.py? My guess is that Spyder is using an event loop to run its python console/interpreter which causes this issue... Commented May 15, 2019 at 16:53
  • Many thanks, that seems to be the issue, is there any way to solve this? Commented May 15, 2019 at 17:01
  • 1
    Adding import nest_asyncio and nest_asyncio.apply() seems to be one solution Commented May 15, 2019 at 17:13
  • Does this answer your question? "asyncio.run() cannot be called from a running event loop" when using Jupyter Notebook Commented Sep 7, 2022 at 10:39

2 Answers 2

30

It's a known problem related to IPython.

One way as you already found is to use nest_asyncio:

import nest_asyncio
nest_asyncio.apply()

The other one is to install older version of tornado:

pip3 install tornado==4.5.3
Sign up to request clarification or add additional context in comments.

4 Comments

The first solution seems to give some running problems for me, installing the older version of tornado seems to work perfectly!
Beware, nested run calls will starve out loops. This monkey patch is very fragile on python / stdlib upgrades.
Is there any reason for not simply using await main() with spyder?
I've started having problems after upgrading databricks cluster to runtime 11.3 (it informs 3.9.5 on sys.version). My code was working perfectly on 10.5 version. Just added the nest_asyncio as above at the start of my notebook and it's resolved.
15

Problem origin

Spyder runs its own event loop

print(asyncio.get_running_loop().is_running()) 
Returns: True

but only one is allowed per thread

cannot be called when another asyncio event loop is running in the same thread

That is why, when we try to create a new event loop with
asyncio.run(main()) it gives us an error:
RuntimeError: asyncio.run() cannot be called from a running event loop

Solution

Except what already proposed with nest_asyncio and tornado I came up with

  1. Attach to an existing Spyder thread event loop by creating a new task
import asyncio

async def main():
    print('Hello world!')

asyncio.create_task(main())
  1. Create new thread (by executing in external terminal) which allows to run our own event loop.
    Top menu Run -> Run configuration per file... -> Execute in the external system terminal enter image description here

Now the code runs in new terminal and works

import asyncio

async def main():
    print('Hello world!')
asyncio.run(main())

2 Comments

This is definetly the better answer. Perfect would be a interpreter-independent version with try: ....create_task(main()) except RuntimeError: asyncio.run(main()). This works fine in Spyder, but still produces some warnings in python shell :(
task = create_task(main()) swallows exceptions. So I added task.add_done_callback(lambda task: task.result()).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.