最近感兴趣研究了一下量化交易,在聚宽(JoinQuant)网站中看到网页中嵌入了Jupyter notebook(多语言支持的Html笔记本应用程序)。而我也经常使用Jupyter测试神经网络等机器学习算法,如果可以把Jupyter架设在自己的网站上,那样随时随地可以用手机跑程序了。下面就研究一下如何在Django中嵌入Jupyter notebook。
使用nbviewer分享Jupter notebook
借助nbviewer实现Jupyter notebook文件分享比较简单,不需要自己架设Jupyter notebook Server,适合分享在静态页面中,但问题是不能动态编写、运行程序,只能显示.ipynb文件当前状态。适合分享排版后的Jupyter笔记,本身就不要动态运行也不想被修改的场景。
- 将编写好的.ipynb文件上传到云端,如果你有自己的云存储比如阿里云OSS就直接上传,并且记录文件网址。如果没有自己的云存储,可以传到Github上,获取上传.ipynb文件的网址。
- 登陆https://nbviewer.jupyter.org/,然后输入相应的ipynb文件链接,即可在线显示,并获取显示jupyter notebook界面的网址。
- 通过iframe将jupyter notebook显示界面嵌入到网页中。对于Django来说,嵌入方式与静态网页基本相同,但要注意生成链接和视图函数。 (1)需要首先创建对应html框架并插入iframe标签和网页按键;
<iframe frameborder='no' scrolling="yes"
style="width:100%;overflow:auto;height:100%;min-height:630px"
src="https://nbviewer.jupyter.org/urls/smartzlink.oss-cn-zhangjiakou.aliyuncs.com/01.ipynb" ></iframe>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav navbar-right">...<li class="cl-effect-11"><a href="{% url 'blog:jupyter' %}"
data-hover="Jupyter">Jupyter</a></li> </ul>
</div><!-- /.navbar-collapse -->
(2) 在views.py文件中创建视图函数;
def jupyter(request): return render(request, 'blog/jupyter.html', context={})
(3)在blog/urls.py文件中增加对应链接。
urlpatterns = [
...
url(r'^jupyter$', views.jupyter, name='jupyter'),
]
本章节的代码位于:smartzlink_step4
Django嵌入自建的Jupyter notebook Server
同样采用iframe嵌入Jupyter,但是嵌入的是自建Jupyter notebook server是自建在服务器的,这样就可以在页面上进行编码、调试和运行代码,可以达到与聚宽网站类似效果。
- 安装Jupyter notebook
pip3 install ipython jupyter notebook
- 生成默认配置文件 运行下面命令,在用户主目录下生成.jupyter文件夹,并且生成jupyter_notebook_config.py配置文件。
jupyter notebook --generate-config
- 生成登陆密钥 运行下面命令,会在.jupyter文件夹下生成jupyter_notebook_config.josn文件,里面包含密码sha值。
jupyter notebook password
- 修改配置文件,实现远程登陆
c.NotebookApp.ip = '0.0.0.0' #允许所有外部IP访问
c.NotebookApp.password = u'sha1:...' #插入生成密码sha值 #运行时不打开本地浏览器
c.NotebookApp.open_browser = False #运行时不打开本地浏览器
c.NotebookApp.port = 8888 #服务端口
c.NotebookApp.allow_root = True #允许在root用户下打开程序
完成上述设置之后,就可以通过服务器直接进入jupyter notebook server。
下载已经可以远程访问jupyter notebook,但是现在还不能直接在页面中通过iframe调用jupyter notebook,因为默 jupyter noteboo 的HTTP Content-Security-Policy (CSP) 安全策略是不允许父类将jupyter notebook页面嵌入到 frame、iframe、object、embed 或 applet中的,所以需要进一步设置jupyter notebook。
(1) 需要修改jupyter notebook配置使其允许指定IP的父类元素内嵌jupyter notebook页面。
c.NotebookApp.tornado_settings =
{ 'headers':{ 'Content-Security-Policy': "frame-ancestors http://47.92.37.254:8000 http://localhost:8000 'self' "}
}
(2) 嵌入后不希望离开打开Jupyter notebook的页面,增加文件 ~/.jupyter/custom/custom.js,设置在本页打开新建页面。
define(['base/js/namespace'], function(Jupyter){Jupyter._target = '_self';});
(3) 修改html页面中iframe标签
<iframe frameborder='no' scrolling="no"
style="width:100%;overflow:auto;height:100%;min-height:630px"
src="http://47.92.37.254:8888" ></iframe>
(4) 通过supervisor设置notebook上电自动启动,然后就可以在网站页面中加载Jupyter notebook server。
[program:smartzlink_jupyter]
command = jupyter notebook
directory=/home/monte3card/notebooks
autostart=true
autorestart=unexpected
user=root
stdout_logfile=/home/monte3card/etc/supervisor/var/log/smartzlink_juputer_stdout.log
stderr_logfile=/home/monte3card/etc/supervisor/var/log/smartzlink_jupyter_stderr.log
网站状态-SmartzLink
本章节的代码位于:smartzlink_step5