将标准Tornado演示推入后台线程,并将IOLoop推到后台线程中,可以在单个脚本中查询服务器。当Tornado服务器是交互对象(参见Dask或类似工具)时,这很有用。
当在Jupyter notebook中运行上述脚本时,服务器和请求客户端都试图在同一线程中打开连接,代码会挂起。构建新的Asyncio循环和/或Tornado IOLoop似乎没有帮助,我怀疑我在Jupyter本身中缺少某些东西。
问题是:是否可能在Jupyter笔记本内部运行一个活动的Tornado服务器,以便标准python“requests”或类似工具可以从主线程连接到它?如果可能,我希望在用户呈现的代码中尽可能避免使用Asyncio,因为对于初学者来说它相对复杂。
import asyncio
import requests
import tornado.ioloop
import tornado.web
from concurrent.futures import ThreadPoolExecutor
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
pool = ThreadPoolExecutor(max_workers=2)
loop = tornado.ioloop.IOLoop()
app = make_app()
app.listen(8888)
fut = pool.submit(loop.start)
print(requests.get("https://localhost:8888"))
在标准的Python脚本中,上述内容完全正常(尽管缺少安全关闭)。Jupyter Notebook 是这些交互式Tornado服务器环境的最佳环境。然而,当涉及到Jupyter时,这个想法就会破裂,因为已经有一个活动运行的循环了:
>>> import asyncio
>>> asyncio.get_event_loop()
<_UnixSelectorEventLoop running=True closed=False debug=False>
当在Jupyter notebook中运行上述脚本时,服务器和请求客户端都试图在同一线程中打开连接,代码会挂起。构建新的Asyncio循环和/或Tornado IOLoop似乎没有帮助,我怀疑我在Jupyter本身中缺少某些东西。
问题是:是否可能在Jupyter笔记本内部运行一个活动的Tornado服务器,以便标准python“requests”或类似工具可以从主线程连接到它?如果可能,我希望在用户呈现的代码中尽可能避免使用Asyncio,因为对于初学者来说它相对复杂。
app/loop
在此情况下不是交互式的。 - Danielapp
无法从 Jupyter 的其他部分访问。例如,如果我有一个方法app.await_results()
,它将阻塞直到操作完成,这在当前模型下是不可能的。 - Daniel