5

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

3
  • It seems like new ipython do not support js api? Commented Jan 23, 2021 at 5:26
  • I don't know jupyter-notebook. But, I think you having issue with print and return. Cause, i think in your method 2 you are running source code like print. And, in say_hello command you are using print function also. So, i think if you write return instead of print in say_hello command. I think it will work... Commented Jan 26, 2021 at 6:54
  • It is not about my function logic. It is about that I can't access IPython and Jupyter objects in my JS code. Commented Jan 28, 2021 at 9:35

1 Answer 1

10
+50

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.