I have some asyncio code which runs fine in the Python interpreter (CPython 3.6.2). I would now like to run this inside a Jupyter notebook with an IPython kernel.
I can run it with
import asyncio asyncio.get_event_loop().run_forever()
and while that seems to work it also seems to block the notebook and doesn't seem to play nice with the notebook.
My understanding is that Jupyter uses Tornado under the hood so I tried to install a Tornado event loop as recommended in the Tornado docs:
from tornado.platform.asyncio import AsyncIOMainLoop AsyncIOMainLoop().install()
However that gives the following error:
--------------------------------------------------------------------------- AssertionError Traceback (most recent call last) <ipython-input-1-1139449343fc> in <module>() 1 from tornado.platform.asyncio import AsyncIOMainLoop ----> 2 AsyncIOMainLoop().install() ~\AppData\Local\Continuum\Anaconda3\envs\numismatic\lib\site- packages\tornado\ioloop.py in install(self) 179 `IOLoop` (e.g., :class:`tornado.httpclient.AsyncHTTPClient`). 180 """ --> 181 assert not IOLoop.initialized() 182 IOLoop._instance = self 183 AssertionError:
Finally I found the following page: http://ipywidgets.readthedocs.io/en/stable/examples/Widget%20Asynchronous.html
so I added a cell with the following code:
import asyncio from ipykernel.eventloops import register_integration @register_integration('asyncio') def loop_asyncio(kernel): '''Start a kernel with asyncio event loop support.''' loop = asyncio.get_event_loop() def kernel_handler(): loop.call_soon(kernel.do_one_iteration) loop.call_later(kernel._poll_interval, kernel_handler) loop.call_soon(kernel_handler) try: if not loop.is_running(): loop.run_forever() finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close()
and in the next cell I ran:
%gui asyncio
That worked but I don't really understand why and how it works. Can someone please explain that to me?
For any asyncio functionality to run on Jupyter Notebook you cannot invoke a run_until_complete(), since the loop you will receive from asyncio. get_event_loop() will be active.
To run a piece of code, click on the cell to select it, then press SHIFT+ENTER or press the play button in the toolbar above. Additionally, the Cell dropdown menu has several options to run cells, including running one cell at a time or to run all cells at once.
You can run the notebook document step-by-step (one cell a time) by pressing shift + enter. You can run the whole notebook in a single step by clicking on the menu Cell -> Run All. To restart the kernel (i.e. the computational engine), click on the menu Kernel -> Restart.
Shortcuts in both modes: Shift + Enter run the current cell, select below. Ctrl + Enter run selected cells.
EDIT FEB 21st, 2019: Problem Fixed
This is no longer an issue on the latest version of Jupyter Notebook. Authors of Jupyter Notebook detailed the case here.
Answer below was the original response that was marked correct by the op.
This was posted quite a bit ago, but in case other people are looking for an explanation and solution to the problem of running asynchronous code inside Jupyter Notebook;
Jupyter's Tornado 5.0 update bricked asyncio functionalities after the addition of its own asyncio event loop:
Thus, for any asyncio functionality to run on Jupyter Notebook you cannot invoke a loop.run_until_complete(...)
, since the loop you will receive from asyncio.get_event_loop()
will be active.
Instead, you must either add the task to the current event loop:
import asyncio loop = asyncio.get_event_loop() loop.create_task(some_async_function())
Or get the results via run_coroutine_threadsafe
:
import asyncio loop = asyncio.get_event_loop() asyncio.run_coroutine_threadsafe(some_async_function(), loop)
This is no longer an issue in the latest jupyter release!
https://blog.jupyter.org/ipython-7-0-async-repl-a35ce050f7f7
Just write an async function, and then await it directly in a jupyter cell.
async def fn(): print('hello') await asyncio.sleep(1) print('world') await fn()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With