提示用戶輸入一段代碼,當(dāng)用戶輸入以后執(zhí)行。這種模式經(jīng)常被稱為REPL(交互式開發(fā)環(huán)境)瞻讽,或者Read-Eval-Print-Loop(讀取﹣求值﹣輸出循環(huán)).jupyter notebook就是這樣一種在web端的交互式開發(fā)環(huán)境鸳吸,如下:
對(duì)應(yīng).ipynb文件的內(nèi)容:
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"pi is rough3.142608\n"
]
}
],
"source": [
"import scala.math.random\n",
"import org.apache.spark._\n",
"val slices = 10\n",
"val n = math.min(100000L * slices, Int.MaxValue).toInt\n",
"val count = sc.parallelize(1 until n, slices).map{ i =>\n",
" val x = random*2 - 1\n",
" val y = random*2 -1\n",
" if (x*x + y*y <1) 1 else 0\n",
" }.reduce(_+_)\n",
"println(\"pi is rough\" + 4.0*count/n)"
]
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Apache Toree - Scala",
"language": "scala",
"name": "apache_toree_scala"
},
"language_info": {
"name": "scala",
"version": "2.11.8"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
IPython 內(nèi)核 所有其它接口,包括Notebook速勇,Qt控制臺(tái)晌砾,ipython控制臺(tái)和其它第三方接口,都使用IPython內(nèi)核烦磁。IPython內(nèi)核是一個(gè)獨(dú)立的進(jìn)程养匈,負(fù)責(zé)執(zhí)行用戶代碼和其它事情,例如計(jì)算可能的補(bǔ)全都伪。前端處理器呕乎,例如notebook和Qt控制臺(tái),使用ZeroMQ傳輸JSON消息與IPython內(nèi)核通信陨晶,前端處理器與IPython內(nèi)核通信使用的協(xié)議詳細(xì)描述請(qǐng)參考Jupyter 消息
Notebook 前端處理器做一些額外的事情猬仁。除了運(yùn)行你的代碼,它還儲(chǔ)存代碼和輸出先誉、以及markdown注釋在一個(gè)可編輯的文檔中湿刽,我們稱這個(gè)文檔為一個(gè)notebook。當(dāng)你保存這個(gè)文檔時(shí)褐耳,它會(huì)從你的瀏覽器發(fā)送到notebook服務(wù)器诈闺,服務(wù)器將文檔保存為.ipynb為拓展名的JSON格式文件,notebook服務(wù)器而不是內(nèi)核漱病,負(fù)責(zé)保存和載入notebook买雾,因此你可以編輯notebook即使你沒(méi)有那種編程語(yǔ)言的內(nèi)核,你僅僅不能運(yùn)行notebook中的代碼杨帽。內(nèi)核不知道notebook文檔任何事情漓穿,它只是在用戶運(yùn)行代碼時(shí)獲取用戶發(fā)送的代碼并執(zhí)行。導(dǎo)出notebooks到其他格式 Jupyter中的工具Nbconvert可以將notebook文件轉(zhuǎn)換到其它格式注盈,例如HTML晃危,LaTex.
使用nbconvert和HTML導(dǎo)出器。當(dāng)你輸入一個(gè)網(wǎng)址老客,它從輸入的網(wǎng)址獲取notebook僚饭,然后將其轉(zhuǎn)換為HTML格式,并將HTML呈現(xiàn)給你胧砰。
Python Notebook中輸入的代碼經(jīng)由瀏覽器發(fā)送給Web服務(wù)器鳍鸵,再由Web服務(wù)器發(fā)送消息到IPython的Kernel執(zhí)行代碼,在Kernel中執(zhí)行代碼所產(chǎn)生的輸出會(huì)再發(fā)送給Web服務(wù)器從而發(fā)送給瀏覽器尉间,完成整個(gè)運(yùn)行過(guò)程偿乖。Web服務(wù)器和Kernel之間采用ZeroMQ進(jìn)行通信击罪。下面為其通信的示意圖:
圖中,Kernel經(jīng)由綠色的DEAL-ROUTER通道接收來(lái)自Web服務(wù)器的命令消息贪薪,并返回應(yīng)答消息媳禁。通過(guò)紅色的PUB-SUB通道傳輸被執(zhí)行代碼所產(chǎn)生的輸出信息。
在Kernel中画切,用戶代碼在一個(gè)用戶環(huán)境(字典)中執(zhí)行竣稽,通常無(wú)法獲得關(guān)于Kernel的信息。但是由于用戶代碼和Kernel在同一進(jìn)程中執(zhí)行霍弹,因此我們可以通過(guò)一些特殊的代碼研究Kernel是如何接收毫别、運(yùn)行并返回消息的。
兩種思路:
一庞萍、從websocket入手
打開一個(gè)新的notebook: http://127.0.0.1:5000/notebooks/Untitled1.ipynb
從chrome調(diào)試面板的Network可以看到拧烦,有個(gè)websocket:ws://127.0.0.1:5000/api/kernels/d13a50b0-6baa-4d5e-8564-95f224daxxxx/channels?session_id=F552491A7C0448A2B5567DE1A71Cxxxx钝计,代碼經(jīng)由它往后端發(fā)送,也經(jīng)由它接收后臺(tái)返回的信息
當(dāng)我們運(yùn)行上頭的print("hello world")時(shí)齐佳,往后臺(tái)發(fā)送如下數(shù)據(jù)
{
"header":
{
"msg_id":"D8FA79DCD7D140DF8F9C37EE15D9FD6D",
"username":"username",
"session":"91608A811CAE4FA6A5E09D37AF68DF32",
"msg_type":"execute_request",
"version":"5.0"
},
"metadata":{},
"content":
{
"code":"print(\"hello world\")",
"silent":false,
"store_history":true,
"user_expressions":{},
"allow_stdin":true,
"stop_on_error":true
},
"buffers":[],
"parent_header":{},
"channel":"shell"
}
接下來(lái)有5個(gè)frames:
{
"parent_header":
{
"username": "username",
"session": "91608A811CAE4FA6A5E09D37AF68DF32",
"version": "5.0",
"msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D",
"msg_type": "execute_request"
},
"msg_type": "status",
"msg_id": "ce11828e-1c2a-4254-962f-2db9e2ff3353",
"content":
{
"execution_state": "busy"
},
"header":
{
"username": "root",
"version": "5.0",
"msg_type": "status",
"msg_id": "ce11828e-1c2a-4254-962f-2db9e2ff3353",
"session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3",
"date": "2017-12-03T20:05:06.816757"
},
"channel": "iopub",
"buffers": [],
"metadata":
{
"timestamp": "1512302706811"
}
}
{
"parent_header":
{
"username": "username",
"session": "91608A811CAE4FA6A5E09D37AF68DF32",
"version": "5.0",
"msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D",
"msg_type": "execute_request"
},
"msg_type": "execute_input",
"msg_id": "116696e7-befa-40c7-98c1-88e32e1e9b63",
"content":
{
"execution_count": 1,
"code": "print(\"hello world\")"
},
"header":
{
"username": "root",
"version": "5.0",
"msg_type": "execute_input",
"msg_id": "116696e7-befa-40c7-98c1-88e32e1e9b63",
"session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3",
"date": "2017-12-03T20:05:06.829865"
},
"channel": "iopub",
"buffers": [],
"metadata":
{
"timestamp": "1512302706826"
}
}
{
"parent_header":
{
"username": "username",
"session": "91608A811CAE4FA6A5E09D37AF68DF32",
"version": "5.0", "msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D",
"msg_type": "execute_request"
},
"msg_type": "stream",
"msg_id": "d3c9ffa1-108f-4ea2-88db-100985fe23d0",
"content":
{
"text": "hello world", "name": "stdout"
},
"header":
{
"username": "root",
"version": "5.0",
"msg_type": "stream",
"msg_id": "d3c9ffa1-108f-4ea2-88db-100985fe23d0",
"session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3",
"date": "2017-12-03T20:05:07.071811"
},
"channel": "iopub",
"buffers": [],
"metadata":
{
"timestamp": "1512302707065"
}
}
{
"parent_header":
{
"username": "username",
"session": "91608A811CAE4FA6A5E09D37AF68DF32",
"version": "5.0",
"msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D",
"msg_type": "execute_request"
},
"msg_type": "execute_reply",
"msg_id": "6ee99d0d-9c92-41ce-be06-39241719f321",
"content":
{
"status": "ok",
"execution_count": 1,
"payload": [],
"user_expressions": {}
},
"header":
{
"username": "root",
"version": "5.0",
"msg_type": "execute_reply",
"msg_id": "6ee99d0d-9c92-41ce-be06-39241719f321",
"session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3",
"date": "2017-12-03T20:05:07.097685"
},
"channel": "shell",
"buffers": [],
"metadata":
{
"timestamp": "1512302707094"
}
}
{
"parent_header":
{
"username": "username",
"session": "91608A811CAE4FA6A5E09D37AF68DF32",
"version": "5.0",
"msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D",
"msg_type": "execute_request"
},
"msg_type": "status",
"msg_id": "32857f80-db87-4775-9350-fe009a8e9c18",
"content": {
"execution_state": "idle"
},
"header":
{
"username": "root",
"version": "5.0",
"msg_type": "status",
"msg_id": "32857f80-db87-4775-9350-fe009a8e9c18",
"session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3",
"date": "2017-12-03T20:05:07.098384"
},
"channel": "iopub",
"buffers": [],
"metadata":
{
"timestamp": "1512302707095"
}
}
在支持WebSocket的瀏覽器中私恬,在創(chuàng)建socket之后×段猓可以通過(guò)onopen本鸣,onmessage,onclose和onerror四個(gè)事件實(shí)現(xiàn)對(duì)socket進(jìn)行響應(yīng)
一個(gè)簡(jiǎn)單的 示例
var ws = new WebSocket(“ws://localhost:8080”);
ws.onopen = function()
{ console.log(“open”);
ws.send(“hello”);
};
ws.onmessage = function(evt)
{
console.log(evt.data)
};
ws.onclose = function(evt)
{
console.log(“WebSocketClosed!”);
};
ws.onerror = function(evt)
{
console.log(“WebSocketError!”);
};
1.var ws = new WebSocket(“ws://localhost:8080”);
申請(qǐng)一個(gè)WebSocket對(duì)象硅蹦,參數(shù)是需要連接的服務(wù)器端的地址荣德,同http協(xié)議使用http://開頭一樣,WebSocket協(xié)議的URL使用ws://開頭童芹,另外安全的WebSocket協(xié)議使用wss://開頭涮瞻。
ws.send(“hello”);
用于將消息發(fā)送到服務(wù)端
2.ws.onopen = function() { console.log(“open”)};
當(dāng)websocket創(chuàng)建成功時(shí),即會(huì)觸發(fā)onopen事件
3.ws.onmessage = function(evt) { console.log(evt.data) };
當(dāng)客戶端收到服務(wù)端發(fā)來(lái)的消息時(shí)假褪,會(huì)觸發(fā)onmessage事件署咽,參數(shù)evt.data中包含server傳輸過(guò)來(lái)的數(shù)據(jù)
4.ws.onclose = function(evt) { console.log(“WebSocketClosed!”); };
當(dāng)客戶端收到服務(wù)端發(fā)送的關(guān)閉連接的請(qǐng)求時(shí),觸發(fā)onclose事件
5.ws.onerror = function(evt) { console.log(“WebSocketError!”); };
如果出現(xiàn)連接生音,處理宁否,接收,發(fā)送數(shù)據(jù)失敗的時(shí)候就會(huì)觸發(fā)onerror事件
我們可以看出所有的操作都是采用事件的方式觸發(fā)的缀遍,這樣就不會(huì)阻塞UI慕匠,使得UI有更快的響應(yīng)時(shí)間,得到更好的用戶體驗(yàn)域醇。
二台谊、從頁(yè)面入手
在stack overflow里找到解答:
var handle_output = function (data) {console.log(data);}
//callbacks.iopub.output is used to get the data from execute
var callbacks = {
iopub : {output : handle_output,}
}
//(read the source F12->static/notebook/js/services/kernels/kernel.js)
//kernel.js/717th lines Kernel.prototype.execute
var kernel = IPython.notebook.kernel;
kernel.execute("print('hello')",callbacks)
kernel.js的function:
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
define('services/kernels/kernel',[
'jquery',
'base/js/utils',
'./comm',
'./serialize',
'base/js/events'
], function($, utils, comm, serialize, events) {
"use strict";
/**
* A Kernel class to communicate with the Python kernel. This
* should generally not be constructed directly, but be created
* by. the `Session` object. Once created, this object should be
* used to communicate with the kernel.
*
* Preliminary documentation for the REST API is at
* https://github.com/ipython/ipython/wiki/IPEP-16%3A-Notebook-multi-directory-dashboard-and-URL-mapping#kernels-api
*
* @class Kernel
* @param {string} kernel_service_url - the URL to access the kernel REST api
* @param {string} ws_url - the websockets URL
* @param {string} name - the kernel type (e.g. python3)
*/
var Kernel = function (kernel_service_url, ws_url, name) {
this.events = events;
this.id = null;
this.name = name;
this.ws = null;
this.kernel_service_url = kernel_service_url;
this.kernel_url = null;
this.ws_url = ws_url || utils.get_body_data("wsUrl");
if (!this.ws_url) {
// trailing 's' in https will become wss for secure web sockets
this.ws_url = location.protocol.replace('http', 'ws') + "http://" + location.host;
}
this.username = "username";
this.session_id = utils.uuid();
this._msg_callbacks = {};
this._msg_queue = Promise.resolve();
this.info_reply = {}; // kernel_info_reply stored here after starting
if (typeof(WebSocket) !== 'undefined') {
this.WebSocket = WebSocket;
} else if (typeof(MozWebSocket) !== 'undefined') {
this.WebSocket = MozWebSocket;
} else {
alert('Your browser does not have WebSocket support, please try Chrome, Safari or Firefox ≥ 6. Firefox 4 and 5 are also supported by you have to enable WebSockets in about:config.');
}
this.bind_events();
this.init_iopub_handlers();
this.comm_manager = new comm.CommManager(this);
this.last_msg_id = null;
this.last_msg_callbacks = {};
this._autorestart_attempt = 0;
this._reconnect_attempt = 0;
this.reconnect_limit = 7;
this._pending_messages = [];
};
/**
* @function _get_msg
*/
Kernel.prototype._get_msg = function (msg_type, content, metadata, buffers) {
return msg;
};
/**
* @function bind_events
*/
Kernel.prototype.bind_events = function () {
};
/**
* Initialize the iopub handlers.
*
* @function init_iopub_handlers
*/
Kernel.prototype.init_iopub_handlers = function () {
};
/**
* GET /api/kernels
*
* Get the list of running kernels.
*
* @function list
* @param {function} [success] - function executed on ajax success
* @param {function} [error] - functon executed on ajax error
*/
Kernel.prototype.list = function (success, error) {
};
/**
* POST /api/kernels
*
* Start a new kernel.
*
* In general this shouldn't be used -- the kernel should be
* started through the session API. If you use this function and
* are also using the session API then your session and kernel
* WILL be out of sync!
*
* @function start
* @param {params} [Object] - parameters to include in the query string
* @param {function} [success] - function executed on ajax success
* @param {function} [error] - functon executed on ajax error
*/
Kernel.prototype.start = function (params, success, error) {
return url;
};
/**
* GET /api/kernels/[:kernel_id]
*
* Get information about the kernel.
*
* @function get_info
* @param {function} [success] - function executed on ajax success
* @param {function} [error] - functon executed on ajax error
*/
Kernel.prototype.get_info = function (success, error) {
};
/**
* DELETE /api/kernels/[:kernel_id]
*
* Shutdown the kernel.
*
* If you are also using sessions, then this function shoul NOT be
* used. Instead, use Session.delete. Otherwise, the session and
* kernel WILL be out of sync.
*
* @function kill
* @param {function} [success] - function executed on ajax success
* @param {function} [error] - functon executed on ajax error
*/
Kernel.prototype.kill = function (success, error) {
};
/**
* POST /api/kernels/[:kernel_id]/interrupt
*
* Interrupt the kernel.
*
* @function interrupt
* @param {function} [success] - function executed on ajax success
* @param {function} [error] - functon executed on ajax error
*/
Kernel.prototype.interrupt = function (success, error) {
};
Kernel.prototype.restart = function (success, error) {
/**
* POST /api/kernels/[:kernel_id]/restart
*
* Restart the kernel.
*
* @function interrupt
* @param {function} [success] - function executed on ajax success
* @param {function} [error] - functon executed on ajax error
*/
};
Kernel.prototype.reconnect = function () {
};
Kernel.prototype._on_success = function (success) {
/**
* Handle a successful AJAX request by updating the kernel id and
* name from the response, and then optionally calling a provided
* callback.
*
* @function _on_success
* @param {function} success - callback
*/
};
Kernel.prototype._on_error = function (error) {
/**
* Handle a failed AJAX request by logging the error message, and
* then optionally calling a provided callback.
*
* @function _on_error
* @param {function} error - callback
*/
};
Kernel.prototype._kernel_created = function (data) {
/**
* Perform necessary tasks once the kernel has been started,
* including actually connecting to the kernel.
*
* @function _kernel_created
* @param {Object} data - information about the kernel including id
*/
};
Kernel.prototype._kernel_connected = function () {
/**
* Perform necessary tasks once the connection to the kernel has
* been established. This includes requesting information about
* the kernel.
*
* @function _kernel_connected
*/
};
Kernel.prototype._kernel_dead = function () {
/**
* Perform necessary tasks after the kernel has died. This closing
* communication channels to the kernel if they are still somehow
* open.
*
* @function _kernel_dead
*/
};
Kernel.prototype.start_channels = function () {
/**
* Start the websocket channels.
* Will stop and restart them if they already exist.
*
* @function start_channels
*/
};
Kernel.prototype._ws_opened = function (evt) {
/**
* Handle a websocket entering the open state,
* signaling that the kernel is connected when websocket is open.
*
* @function _ws_opened
*/
};
Kernel.prototype._ws_closed = function(ws_url, error) {
/**
* Handle a websocket entering the closed state. If the websocket
* was not closed due to an error, try to reconnect to the kernel.
*
* @function _ws_closed
* @param {string} ws_url - the websocket url
* @param {bool} error - whether the connection was closed due to an error
*/
};
Kernel.prototype._schedule_reconnect = function () {
/**
* function to call when kernel connection is lost
* schedules reconnect, or fires 'connection_dead' if reconnect limit is hit
*/
};
Kernel.prototype.stop_channels = function () {
/**
* Close the websocket. After successful close, the value
* in `this.ws` will be null.
*
* @function stop_channels
*/
};
Kernel.prototype.is_connected = function () {
/**
* Check whether there is a connection to the kernel. This
* function only returns true if websocket has been
* created and has a state of WebSocket.OPEN.
*
* @function is_connected
* @returns {bool} - whether there is a connection
*/
// if any channel is not ready, then we're not connected
};
Kernel.prototype.is_fully_disconnected = function () {
/**
* Check whether the connection to the kernel has been completely
* severed. This function only returns true if all channel objects
* are null.
*
* @function is_fully_disconnected
* @returns {bool} - whether the kernel is fully disconnected
*/
return (this.ws === null);
};
Kernel.prototype._send = function(msg) {
/**
* Send a message (if the kernel is connected) or queue the message for future delivery
*
* Pending messages will automatically be sent when a kernel becomes connected.
*
* @function _send
* @param msg
*/
}
Kernel.prototype.send_shell_message = function (msg_type, content, callbacks, metadata, buffers) {
/**
* Send a message on the Kernel's shell channel
*
* If the kernel is not connected, the message will be buffered.
*
* @function send_shell_message
*/
return msg.header.msg_id;
};
Kernel.prototype.kernel_info = function (callback) {
/**
* Get kernel info
*
* @function kernel_info
* @param callback {function}
*
* When calling this method, pass a callback function that expects one argument.
* The callback will be passed the complete `kernel_info_reply` message documented
* [here](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info)
*/
};
Kernel.prototype.comm_info = function (target_name, callback) {
/**
* Get comm info
*
* @function comm_info
* @param callback {function}
*
* When calling this method, pass a callback function that expects one argument.
* The callback will be passed the complete `comm_info_reply` message documented
* [here](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm_info)
*/
};
Kernel.prototype.inspect = function (code, cursor_pos, callback) {
/**
* Get info on an object
*
* When calling this method, pass a callback function that expects one argument.
* The callback will be passed the complete `inspect_reply` message documented
* [here](https://jupyter-client.readthedocs.io/en/latest/messaging.html#object-information)
*
* @function inspect
* @param code {string}
* @param cursor_pos {integer}
* @param callback {function}
*/
};
Kernel.prototype.execute = function (code, callbacks, options) {
/**
* Execute given code into kernel, and pass result to callback.
*
* @async
* @function execute
* @param {string} code
* @param [callbacks] {Object} With the following keys (all optional)
* @param callbacks.shell.reply {function}
* @param callbacks.shell.payload.[payload_name] {function}
* @param callbacks.iopub.output {function}
* @param callbacks.iopub.clear_output {function}
* @param callbacks.input {function}
* @param {object} [options]
* @param [options.silent=false] {Boolean}
* @param [options.user_expressions=empty_dict] {Dict}
* @param [options.allow_stdin=false] {Boolean} true|false
*
* @example
*
* The options object should contain the options for the execute
* call. Its default values are:
*
* options = {
* silent : true,
* user_expressions : {},
* allow_stdin : false
* }
*
* When calling this method pass a callbacks structure of the
* form:
*
* callbacks = {
* shell : {
* reply : execute_reply_callback,
* payload : {
* set_next_input : set_next_input_callback,
* }
* },
* iopub : {
* output : output_callback,
* clear_output : clear_output_callback,
* },
* input : raw_input_callback
* }
*
* Each callback will be passed the entire message as a single
* arugment. Payload handlers will be passed the corresponding
* payload and the execute_reply message.
*/
return this.send_shell_message("execute_request", content, callbacks);
};
/**
* When calling this method, pass a function to be called with the
* `complete_reply` message as its only argument when it arrives.
*
* `complete_reply` is documented
* [here](https://jupyter-client.readthedocs.io/en/latest/messaging.html#complete)
*
* @function complete
* @param code {string}
* @param cursor_pos {integer}
* @param callback {function}
*/
Kernel.prototype.complete = function (code, cursor_pos, callback) {
return this.send_shell_message("complete_request", content, callbacks);
};
/**
* @function send_input_reply
*/
Kernel.prototype.send_input_reply = function (input) {
return msg.header.msg_id;
};
/**
* @function register_iopub_handler
*/
Kernel.prototype.register_iopub_handler = function (msg_type, callback) {
this._iopub_handlers[msg_type] = callback;
};
/**
* Get the iopub handler for a specific message type.
*
* @function get_iopub_handler
*/
Kernel.prototype.get_iopub_handler = function (msg_type) {
return this._iopub_handlers[msg_type];
};
/**
* Get callbacks for a specific message.
*
* @function get_callbacks_for_msg
*/
Kernel.prototype.get_callbacks_for_msg = function (msg_id) {
};
/**
* Clear callbacks for a specific message.
*
* @function clear_callbacks_for_msg
*/
Kernel.prototype.clear_callbacks_for_msg = function (msg_id) {
if (this._msg_callbacks[msg_id] !== undefined ) {
delete this._msg_callbacks[msg_id];
}
};
/**
* @function _finish_shell
*/
Kernel.prototype._finish_shell = function (msg_id) {
};
/**
* @function _finish_iopub
*/
Kernel.prototype._finish_iopub = function (msg_id) {
};
/**
* Set callbacks for a particular message.
* Callbacks should be a struct of the following form:
* shell : {
*
* }
*
* @function set_callbacks_for_msg
*/
Kernel.prototype.set_callbacks_for_msg = function (msg_id, callbacks) {
};
Kernel.prototype._handle_ws_message = function (e) {
};
Kernel.prototype._finish_ws_message = function (msg) {
};
Kernel.prototype._handle_shell_reply = function (reply) {
return promise;
};
/**
* @function _handle_payloads
*/
Kernel.prototype._handle_payloads = function (payloads, payload_callbacks, msg) {
return Promise.all(promise);
};
/**
* @function _handle_status_message
*/
Kernel.prototype._handle_status_message = function (msg) {
};
/**
* Handle clear_output message
*
* @function _handle_clear_output
*/
Kernel.prototype._handle_clear_output = function (msg) {
};
/**
* handle an output message (execute_result, display_data, etc.)
*
* @function _handle_output_message
*/
Kernel.prototype._handle_output_message = function (msg) {
};
/**
* Handle an input message (execute_input).
*
* @function _handle_input message
*/
Kernel.prototype._handle_input_message = function (msg) {
};
/**
* Dispatch IOPub messages to respective handlers. Each message
* type should have a handler.
*
* @function _handle_iopub_message
*/
Kernel.prototype._handle_iopub_message = function (msg) {
};
/**
* @function _handle_input_request
*/
Kernel.prototype._handle_input_request = function (request) {
};
return {'Kernel': Kernel};
});
參考文章:
http://blog.just4fun.site/jupyter-notebook-architecture.html
http://blog.just4fun.site/jupyter-notebook-architecture-hack.html
https://www.tuicool.com/articles/naqIza
http://flamepeak.com/2016/09/12/Jupyter-official-docs-translate-20160912/
https://jupyter-client.readthedocs.io/en/latest/messaging.html#messaging
http://jupyter-notebook.readthedocs.io/en/stable/comms.html
http://hyry.dip.jp/tech/slice/slice.html/36
http://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Connecting%20with%20the%20Qt%20Console.html?highlight=messaging#The-Frontend/Kernel-Model
https://github.com/junjunwudi/zmq-pykernel
https://media.readthedocs.org/pdf/jupyter-notebook/4.x/jupyter-notebook.pdf
https://github.com/ipython/ipython/wiki/IPEP-16%3A-Notebook-multi-directory-dashboard-and-URL-mapping#create_new_notebook
https://stackoverflow.com/questions/26435653/how-do-i-embed-an-ipython-notebook-in-an-iframe-new
http://www.tornadoweb.org/en/stable/web.html#request-handlers
http://jupyter-client.readthedocs.io/en/latest/messaging.html#custom-messages
http://jupyter-notebook.readthedocs.io/en/latest/extending/handlers.html
http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml
http://Check.torproject.org
https://gist.github.com/disarticulate/d06069ff3e71cf828e5329beab8cb084
https://stackoverflow.com/questions/31357718/ipython-javascript-client-api/42418784#42418784
https://www.cnblogs.com/lxtblogs/p/4947898.html
http://jupyter-client.readthedocs.io/en/latest/messaging.html
http://jupyter-notebook.readthedocs.io/en/latest/frontend_config.html#configuring-the-notebook-frontend
http://ipython.org/ipython-doc/stable/development/messaging.html