I have been trying to write some functionality that allows my Python package to prompt a user for input through Javascript. The idea would be (1) have a python function call javascript (2) javascript prompts user for input (3) javascripts makes call to IPython kernel to transfer input back to Python (4) control flow returns to python function, which can now access variable. Having read
https://jakevdp.github.io/blog/2013/06/01/ipython-notebook-javascript-python-communication/, I thought this would be easy to adapt.
I show an example at
https://github.com/micahjsmith/example-jupyter-bidir-comm-fn. (Note that in my example, I additionally attempted to write a utility class `DescriptionStore` that uses `threading.Event` to deal with the fact that Javascript has async execution. This turns out to be irrelevant.)
In my example notebook, I import an object of a class I write that manages this sort communication. Then, I prompt the user for input (`a.prompt_user`) and try to print out that input from python. What happens? The part of my python function that attempts to access the user input times out. I realize that in the kernel's queue, the entire cell must return before the code that I add via `IPython.notebook.kernel.execute` can run. Thus, in
https://github.com/micahjsmith/example-jupyter-bidir-comm-fn/blob/master/ex/__init__.py#L97, we wait for the Javascript-created call to set the python variable to complete, but it cannot complete until the original python function returns. So there is a deadlock, which is only broken by the timeout. Once the python function terminates, the Javascript executes successfully (console log shown in
https://github.com/micahjsmith/example-jupyter-bidir-comm-fn/blob/master/output.txt) but the original python function cannot access the user input.
Sure, I could also prompt for input using `raw_input` or similar, but I had thought this was going to be easy to get working.
What could I do here? I want to hide all of this functionality within a single python function call, so splitting into two cells is not an option. I don't know if nbextensions would address this type of problem. I don't know of any other way to enable communication of the user input besides setting up a separate web server, communicating with this webserver from JS without a call into the IPython kernel, and then accessing webserver from Python as well.
Thanks,
Micah