Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot call Python function from Javascript in Notebook

I would like to call the function say_hello in Jupyter Notebook.

def say_hello():
  print('hello')

%%javascript
//What have been tried
// Method 1
var kernel = IPython.notebook.kernel;
kernel.execute("say_hello()", {"output": callback});

// Method 2
Jupyter.notebook.kernel.execute("say_hello()")

Both methods throw ReferenceError in the browser console.

VM5326:7 Uncaught ReferenceError: IPython is not defined
    at send_message (<anonymous>:7:22)
    at onClickSendMessage (<anonymous>:12:9)
    at HTMLButtonElement.onclick (app.ipynb:1)

version : JupterLab 3.5, IPython 7.16, Python 3.9.1

like image 726
ppn029012 Avatar asked Jan 21 '21 08:01

ppn029012


People also ask

Can you call python functions from JavaScript?

Use ajax to Call Python From JavaScript. AJAX stands for Asynchronous JavaScript and XML. It utilizes the XMLHttpRequest object to communicate with servers.

Can you use JavaScript in Jupyter notebook?

Jupyter Notebooks are documents that contain a mix of live code (Python, R, Julia, JavaScript, and more), visualizations, and narrative text (Markdown). They're useful for breaking down concepts in a story telling form, where you can give some context and show the code below along with interactive visualizations.


Video Answer


1 Answers

The ReferenceError that you're getting is caused by Jupyter and IPython globals not being available in Jupyter Lab at all. You'd have to write a JupyterLab extension yourself.

These things do work in Jupyter Notebooks though. Both of the methods that you tried are a good start but need some improvements.

We need 3 cells - Python, HTML, and JS one.

  1. let's just define the method we want to invoke from JS in Python.
def say_hello():
    print('hello')
  1. We need to create a cell output, where the JS will be writing the results of the execution.
%%html
<div id="result_output">
  1. We execute the Python function, and handle the execution result in a callback. From the callback, we'll fill the result text into the output that we created above.
%%javascript
const callbacks = {
    iopub: {
        output: (data) => {
            // this will print a message in browser console
            console.log('hello in console')

            // this will insert the execution result into "result_output" div
            document.getElementById("result_output").innerHTML = data.content.text
        }
    }
};

const kernel = Jupyter.notebook.kernel
kernel.execute('say_hello()', callbacks)

Some notes:

  • your 2nd method would be good enough if you didn't need to see the result, the execution is executed, just the results from kernel are not handled (you can see that in Network tab in browser devtools in Websocket request messages)
  • in your method 1 you use callback but you don't define it - that would lead to another ReferenceError
  • using const is better than using var in JS
  • Jupyter.notebook.kernel is the same as IPython.notebook.kernel
like image 50
Jakub Žitný Avatar answered Oct 21 '22 23:10

Jakub Žitný