ipykernel icon indicating copy to clipboard operation
ipykernel copied to clipboard

javascript to python communication not working properly when "Run All" cells

Open Crypto-Spartan opened this issue 5 years ago • 2 comments

This issue was first documented here. I'm going to copy the initial issue comment since it displays a good example.

image

It turns out that it works well (the last print for num shows 43) but only when I execute this cell by cell. But if I execute it by clicking the "Run All" menu, or by calling in a js file the "notebook.execute_all_cells()" function, the num variable is never modified from the js code.

The idea is that I have some special notebooks where I need to execute every cell when it loads, but some cells depend on a python variable filled from javascript. I've tried to delay the last cell execution time enough so the previous cell is finished, but since the cells execution is linear, I don't think this could solve my problem.

Can someone point me a way on how to do this?

Crypto-Spartan avatar Oct 27 '20 15:10 Crypto-Spartan

I have a use-case where the javascript would be creating the variable instead of python. If i run the cells one at a time, it works great. If I click "run all" it breaks.

I tried adding this in the cell after my %%javascript

while 'my_var' not in locals():
    await asyncio.sleep(1)

Unfortunately, this didn't work, The code was just in an indefinite await period.

Crypto-Spartan avatar Oct 27 '20 15:10 Crypto-Spartan

So it's still unclear what the deal is with Run All, but this.set_dirty(true) certainly looks interesting :)

I want to be able to rerun and publish notebooks with one button. For that I need the notebook name from the Javascript, and with RunAll it does not enter the global name space until all cells are done running. This is my workaround, allowing to run just the first cell. Hope it's useful for others who need it.

RunAllFromFirstCell

Run All still won't work, but hitting Shift+Enter from first cell works:

from IPython.display import display, Javascript
class NotebookRunner:
    JS = """
    Jupyter.notebook.kernel.execute(
        "NB_NAME = " + "\'" + window.document.getElementById("notebook_name").innerHTML + "\'"
    );
    function runCellsBelow() {
        var cells = Jupyter.notebook.get_cells();
        for (var i = Jupyter.notebook.get_selected_index(); i < cells.length; i++) {
            if (cells[i].cell_type === 'code') {
                Jupyter.notebook.execute_cell_range(i, i + 1);
            }
        }
    }
    runCellsBelow();
    Jupyter.notebook.save_notebook();"""
    def __init__(self):
        display(Javascript(self.JS))
    def publish(self, nb_name=None, **kwargs):
        if nb_name is None:
            global NB_NAME  # injected into python namespace by JS
            nb_name = NB_NAME
        print(f"publishing {nb_name}")
nr = NotebookRunner()

liquidcarbon avatar Dec 15 '23 07:12 liquidcarbon