对jupyter notebook的分析、扩展与hack
文章目录
大纲
本文关心代码在jupyter notebook里从前端传往后端的过程,并试图获取到钩子,因为我最近项目的缘故(可以参考我之前的文章),分析完通信过程,我将演示如何扩展和hack jupyter notebook
在接下来动手实践部分将演示如何将其以iframe嵌入到外部网页网页中(在概念上是嵌入一种资源)
实验环境
- ubuntu 14.04
- python 2.7.6
- jupyter 4.3.0
安装jupyter(notebook)
|
|
运行
jupyter notebook --no-browser --port 5000 --ip=0.0.0.0
我将其跑在5000端口,并接收所有ip的请求
关于启动参数,不熟悉的同学可以参考我之前文章
值得注意的是第一次手动登陆,需要输入token,如果你没加入–no-brower,会自动打开http://127.0.0.1:5000/?token=d311b2834ac7337157c54aaba8d9a524ce48f7597c91xxxx
,验证一次之后,浏览器就有cookie了,之后只需要127.0.0.1:5000
就可访问
分析
从websocket入手
打开一个新的notebook: http://127.0.0.1:5000/notebooks/Untitled1.ipynb
从chrome调试面板的Network可以看到,有个websocket:ws://127.0.0.1:5000/api/kernels/d13a50b0-6baa-4d5e-8564-95f224daxxxx/channels?session_id=F552491A7C0448A2B5567DE1A71Cxxxx
,代码经由它往后端发送,也经由它接收后台返回的信息
当我们运行上头的print(“hello world”)时,往后台发送如下数据
|
|
接下来有5个frames
其中包含了代码执行的结果
那么我们只要模拟建立这样的websocket,就拿到所要的钩子了,可以自如地运行代码
从页面入手
除了建立websocket,我们也可以找找js中钩子
这个问题在stack overflow里找到解答,方法如下
|
|
如此一来我们找到了第二种钩子
消息是用websocket传输的,你可以试试实时性:kernel.execute("for i in range(5):import time;time.sleep(1);print('hello')",callbacks)
嵌入到外部页面中
接下来的部分,演示如何将jupyter notebook嵌入到外部页面里,如此一来可以利用jupyter强大的特性做很多好玩的东西,诸如各种语言的线上IDE
首先建立一个前端页面(my_test.html),然后以iframe的方式引入jupyter notebook(关于iframe的属性可以参考这里),接下来在外部网页中与其互操作
从建立网页开始
|
|
噢报错了,这个问题这里有描述:How do I embed an Ipython Notebook in an iframe,解决方案这个比较靠谱:Can’t use Notebook inside an iframe
解决方案是生成配置文件:jupyter notebook --generate-config
,做些配置。往~/.jupyter/jupyter_notebook_config.py
加入c.NotebookApp.tornado_settings = { 'headers': { 'Content-Security-Policy': "frame-ancestors 'self' *" } }
现在没有问题啦 (注意不要直接打开my_test.html,使用网络访问它(python -m SimpleHTTPServer))
采用postMessage来传递消息
因为jupyter与外部页面可能存在跨域问题(别怕,最复杂的情况,也就是跨域了),我打算采用HTML5 postMessage来处理这个问题
postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
往iframe里发送消息
|
|
扩展jupyter notebook
为了在jupyter notebook中监听到外部网页发过来的消息,并给予响应,我们需要为其写js扩展,哈哈别紧张,jupyter设计得很漂亮,扩展它很简单(可能需要安装:pip install widgetsnbextension
)
进入~/.ipython/nbextensions
,
创建我们的扩展(iframe_extension.js):
|
|
在外部网页等待iframe的消息
|
|
大功告成!
文章作者 种瓜
上次更新 2017-03-22