Jupyter Notebook 跨域連接 Kernel 的方法

通常一個新的 Notebook 在打開的時候,會自動連接當前服務器,創建一個 Session 和一個 Kernel 進程。該 Session 綁定在該 nb(notebook 簡稱,下同) 的路徑上,因此你要你的 server 不停,無論刷新 nb 還是打開該 nb 的一個新 tab,該 session 都是同一個 session,kernel 也是同一個 kernel。

以上是 Notebook 基本的前後端交互流程,本文關注的是當 nb 與 Kernel 不在同一個域下時,如何跨域連接的問題。即假設 nb 的地址是 a.com/xx.ipynb,但我們想連接 b.com 的一個 kernel。

修改後端地址

首先是創建 Session 的調用,該調用發生在 session.js 第 122 行

utils.ajax(this.session_service_url, {

這裏需要修改爲你想要連接的域名,比如 'http://b.com' + this.session_service_url

session 與 kernel 創建完成後,nb 與 kernel 的交互會使用 websocket 通道。ws 地址是類似 ws://localhost 這樣的格式,定義在 notebook.html 模板中,在打開 nb 時由 server 進行渲染:

data-ws-url="{{ws_url | urlencode}}"

這兩處修改爲跨域地址後,你的 nb 就會自動向新服務器發請求,那麼自然你的新服務器需要在響應中添加跨域頭,這一點可以簡單通過修改配置文件實現:

c.NotebookApp.allow_origin = '*'

該配置項會在 /base/handlers.py 中被訪問:

[@property](https://my.oschina.net/property)
def allow_origin(self):
    """Normal Access-Control-Allow-Origin"""
    return self.settings.get('allow_origin', '')

處理認證

當然 server 不是對連接來者不拒的。在認證上仍有兩處需要處理:

一是 xsrf token 認證,該認證可以在配置文件中關掉:

c.NotebookApp.disable_check_xsrf = True

二是用戶登錄認證。server 默認使用 token 的方式,該 token 會在渲染 nb 的時候寫入 page.html 裏:

data-jupyter-api-token="{{token | urlencode}}"

或者想直接繞過 auth 過程的話,修改 base/handlers.py 裏的 get_current_user 方法即可。

完成以上修改後,跨域連接 kernel 的功能就可以實現了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章