问题
Below is a draft for using the Python kernel of the Jupyter notebook to execute Python code from a custom JavaScript client and here is a related question:
Where is a docs for Jupyter front-end extensions JavaScript API?
My draft works for some examples. However, I have still some timing issues.
When executing the following python code with my method executePythonCode
, first the callback shell
is called, resolving my promise. My calling main code will continue execution. Later on, the iopub
callback is called, giving me the wanted text content.
file = open("D:/forecast4/trunk/databases/Demo/template.xml", "r")
print(file.read())
However, I would expect the iopub
to be called first and the shell
to be called second. I want my calling code to wait until the text has been retrieved.
I tried to remove the resolve();
command in the shell
part, so that my promise is not resolved too early. That works for the above text reading example.
However, when executing code without output, the Promise is never resolved. Therefore, I seem to need that resolve() call in the shell
callback.
=>Is there a bug in the execution order of the execute method of the Jupyter kernel?
Or is this the expected behavior? If so, what is the recommended way to use the execute method / how should I adapt my code so that my "JupyterTerminal" can be used in a general way?
Example on how to use Jupyter notebook kernel to execute Python code from a custom JavaScript client (still has some timing issues):
export default class JupyterTerminal {
constructor(jupyter){
this.__kernel = jupyter.notebook.kernel;
}
async executePythonCode(pythonCode){
var self=this;
return new Promise(function(resolve, reject) {
var isResolved=false;
var callbacks = {
shell : {
reply : (data)=>{
var content = data.content
switch(content.status){
case 'ok':
isResolved=true;
resolve();
break;
case 'error':
reject(content.evalue)
break;
default:
throw new Error('Not yet implemented content status "' + content.status + '"');
}
},
},
iopub : {
output : (data)=>{
var content = data.content;
switch(content.name){
case 'stderr':
if(isResolved){
var message = 'Could not handle strr output while executing Python code '
+'because Promise already has been resolved:\n' + content.text;
console.error(message);
}
reject(content.text);
break;
case 'stdout':
if(isResolved){
var message = 'Could not handle stout output while executing Python code '
+'because Promise already has been resolved:\n' + content.text;
console.error(message);
}
resolve(content.text);
break;
case undefined:
reject(content.ename + ': ' + content.evalue);
break;
default:
throw new Error('Not yet implemented content type "' + content.name + '"');
}
}
}
};
self.__kernel.execute(pythonCode, callbacks);
});
}
}
来源:https://stackoverflow.com/questions/55828900/how-to-correctly-use-kernel-execute-method-of-jupyter-notebook-in-javascript-ti