I was unable to reproduce the behavior you are seeing. Using the code you supplied, I did not see the variables notebook_name or notebook_path created at all. Suspecting I made a mistake, I experimented with variations but had no luck with creating those variables (visible inside my Python kernel). I inserted a console.log('howdy') into the function and verified that it was indeed getting executed, but still what happens inside the IPython.notebook.kernel.execute(...) remained a bit of a mystery.
This made me curious so I experimented with creating the following function, derived from one of yours:
def get_notebook_name_from_dom():
'''Execute JS code to save Jupyter notebook name to variable notebookName'''
from IPython.core.display import Javascript, display_javascript
js = Javascript(
"""
var theName = window.document.getElementById("notebook_name").innerHTML;
var command = "notebookName = " + "'" + theName + "'";
IPython.notebook.kernel.execute(command);
"""
)
return display_javascript(js)
Executing this, I do see notebookName appear as a variable in my Python kernel and it is populated with the correct name of my Notebook from the start. (No initial value of None as you experienced.)
This is as far as I got:
I hope that my above example function is useful to you.
The magic that powers IPython.notebook.kernel.execute(...) and fully debugging it is perhaps worth further investigation in the future.
It is possible, but merely a guess, that Jupyter’s code which populates variables in the Python kernel from the JavaScript engine does so asynchronously – this could explain seeing an initial value of None followed by a str later. It is also possible, but again merely a guess, that the act of performing name resolution on a variable in the Jupyter notebook triggers or otherwise awakens some of the IPython.notebook.kernel code involving population of these variables – this could explain seeing a different value for such variables not based upon time but based upon access attempts. Beware that these guesses may be very incorrect.
Does the code “behind the scenes” powering IPython.notebook.kernel change over time? Yes, of course. So differences in behavior (what you experienced versus me) across different versions of Jupyter are to be expected.
I am not sure that the above really helps you but I hope that my example function might provide a more stable way of accessing this information about the notebook, especially across different versions of Jupyter.
Curiously, I did finally get a variation of your original function to finally populate a variable, accessible in the Python kernel. But I still have not seen the behavior you originally described where an initial value of None is seen and later a str.
I believe what I have experienced in my experiments could signal potential silent failures inside the IPython.notebook.kernel functionality. My example function for extracting information from the DOM may be no more stable than any other approach through the IPython.notebook.kernel mechanisms.