How to correctly use kernel.execute method of Jupyter notebook in Javascript (timing issues)?

你说的曾经没有我的故事 提交于 2021-02-19 08:28:22

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!