如何在 Jupyter 笔记本中运行 Python 异步代码? [英] How do I run Python asyncio code in a Jupyter notebook?

查看:43
本文介绍了如何在 Jupyter 笔记本中运行 Python 异步代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些在 Python 解释器 (CPython 3.6.2) 中运行良好的异步代码.我现在想在带有 IPython 内核的 Jupyter notebook 中运行它.

我可以运行它

导入异步asyncio.get_event_loop().run_forever()

虽然这似乎有效,但它似乎也挡住了笔记本,并且似乎与笔记本不兼容.

我的理解是 Jupyter 在幕后使用 Tornado 所以我尝试安装 Tornado 事件Tornado 文档中推荐的循环:

from tornado.platform.asyncio import AsyncIOMainLoopAsyncIOMainLoop().install()

但是会出现以下错误:

---------------------------------------------------------------------------AssertionError Traceback(最近一次调用最后一次)<ipython-input-1-1139449343fc>在 <module>()1 从 tornado.platform.asyncio 导入 AsyncIOMainLoop---->2 AsyncIOMainLoop().install()~AppDataLocalContinuumAnaconda3envs
umismaticlibsite-packages	ornadoioloop.py in install(self)179 `IOLoop`(例如,:class:`tornado.httpclient.AsyncHTTPClient`).第180话-->181 断言不是 IOLoop.initialized()第182话183断言错误:

最后我找到了以下页面:

因此,对于在 Jupyter Notebook 上运行的任何异步功能,您不能调用 loop.run_until_complete(...),因为您将从 asyncio.get_event_loop() 将被激活.

相反,您必须将任务添加到当前事件循环:

import asyncioloop = asyncio.get_event_loop()loop.create_task(some_async_function())

或者通过run_coroutine_threadsafe获取结果:

import asyncioloop = asyncio.get_event_loop()asyncio.run_coroutine_threadsafe(some_async_function(),循环)

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()

~AppDataLocalContinuumAnaconda3envs
umismaticlibsite- packages	ornadoioloop.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?

解决方案

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)

这篇关于如何在 Jupyter 笔记本中运行 Python 异步代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆