Problem displaying output from Voila page

Hi,
I am trying to use Voila to create an interactive web page based on a Jupyter notebook, and I have run into a problem: I can create ipywidgets, including a run button, that run fine in the notebook. But, when I run Viola, the widgets appear and function, but don’t generate any output. I am particularly interested in outputting matplotlib plots and animations, but the problem appears with a simple print statement as well. Here is a simple example:

import ipywidgets as widgets
from IPython.display import display
def sayHello(b):
    print('Hello world!')

run_button = widgets.Button(
      description = 'run'
)
run_button.on_click(sayHello)
display(run_button)

It works just fine in the Jupyter notebook, and the button appears on the Voila page. But pressing the button doesn’t generate any output.

Any suggestions would be greatly appreciated!
Thanks,
Davidd

Voila in the long run is going to be worth the investment in time to learn. (And that was a good suggestion from your other post.) However, there is also Appmode that makes things a little simpler than Voila because the output is what you see but not the code. With Voila you have to make sure you are generating output in ipywidgets. You may get farther faster with Appmode for now. Perhaps? Or it might come in handy to know about Appmode later.

I believe the specific issue with your demo code is that you need to specify a place for the output from the function to display in that will be updated after the button is pressed, that will be in widgets.Output(). Try this:

# sort of based on https://github.com/voila-dashboards/voila-material/issues/18
import ipywidgets as widgets
from IPython.display import display
output = widgets.Output()

@output.capture(clear_output=False,wait=True) # based on https://github.com/jupyter-widgets/ipywidgets/issues/1846 and https://ipywidgets.readthedocs.io/en/latest/examples/Output%20Widget.html
def sayHello(b):
    print('Hello world!')

run_button = widgets.Button(
      description = 'run'
)
run_button.on_click(sayHello)
display(run_button)
output

(You can change the line @output.capture(clear_output=False,wait=True) to @output.capture(clear_output=True,wait=True) if you want it to not to keep adding more printed copies of the text below each time and instead just write over what was there. The latter is probably what you want in most real cases as you’d probably be updating the text there by overwriting it and not adding a longer list of output text. )

I have done static and interactive plots in Voila. Go to here. If you go to https://github.com/fomightez/3Dscatter_plot-binder and launch Binder and then choose the notebook listed as ‘3D scatter plot using data in a file and Voila interface’. That is a pretty advanced interface as you’ll see. I have some more basic interfaces working at https://github.com/fomightez/communication_voila , and something among them might be more helpful for you understanding displaying basic plots than the advanced examples in the Voila Gallery. Animations or interactive plots are you trying to do? I have yet to do animations in Voila, but animations in general can be tricky given the classic notebook interface and JupyterLab handling them differently, see here.

Wayne,
Thanks for your suggestions. Unfortunately, adding the Output widget and calling it, as you suggest, doesn’t seem to work.

I’ve been trying appmode, too, and have made a bit of progress there. But, is there a mechanism, within Binder, to provide a link directly to the app? If users have to start up the Binder repo, choose the notebook and then enter appmode, it’s not that much of a gain over just running a command, already typed in, in the notebook.

Thanks,
David

a) Sorry, I needed the decorator there and not commented out. With that then you can change select clear_output=False or clear_output=True on that line with the decorator depending on your preferences for printing more copies of ‘Hello World’ or write over the one that is there, which only makes it look like something happens the first time in this case. I edited my code in the answer above.

b) You can directly start in appmode. This is from the page on appmode:

Alternatively one can change the url from baseurl/notebooks/foo.ipynb to baseurl/apps/foo.ipynb . This also allows for direct links into appmode.

If you hover over the launch binder badge at the appmode page you’ll get a an example of how to hand edit the typical MyBinder URL to launch in appmode. The link is:

https://mybinder.org/v2/gh/oschuett/appmode/master?urlpath=%2Fapps%2Fexample_app.ipynb

Note the use of %2F to escape the forward slashed in the URL.

1 Like

Thanks for your follow up. In the meantime, I found another solution on the web. For my simple example, the code looks like:

import ipywidgets as widgets
from IPython.display import display,clear_output
def sayHello(b):
    global i
    i+=1
    with out:
        clear_output(wait=True)
        display('Hello world*' + str(i)+'!')
 i=0
out = widgets.Output()
display(out)

run_button = widgets.Button(
    description = 'run'
    )
run_button.on_click(sayHello)
display(run_button)

In this version, the output is 'Hello world*i", where i is incremented in each time the button is clicked.

Now, I think that I have just one more thing that I need help with. I have the full project that I am working with on binder, and it runs there. I can also use voila on binder, and everything is good. But, what I haven’t figured out is how to create a direct link to the voila page for users.

The docs say:
3. Go to mybinder.org and enter the URL of the repository.
4. In Path to a notebook file , select URL and use the Voilà endpoint: /voila/render/path/to/notebook.ipynb
5. Click Launch .

It’s the part about the Voila endpoint that I don’t understand. I presume that “path/to” is to be replaced with a path to the notebook. But, I have tried using the literal example (with the name of my notebook file). I have also tried leaving out ‘path/to/’, without success. It seems like I need to replace 'path/to/ with something, but I can’t figure out what.

As always, any help will be greatly appreciated.
David

Understandably, it is a little tricky to do. In fact, I think the documentation you are referring to is slightly wrong presently, and that is because things are in flux about handling some aspects of the proxy forwarding, I believe.

You don’t want the path/to part.

Those directions you referenced will get you very close, but then you still at present need to change one more thing in the link the MyBinder.org page generates. You cannot just click launch. The MyBinder.org page presently makes a link with filepath and urlpath is needed for the forwarding/proxy stuff (or at least I think that is reason).
Example of generating one at MyBinder.org following through to step #4 of what you posted from the documentation:


The URL it offers at this point is close. Next, you need to copy what is under Copy the URL below... to your favorite text editor, and then need to change filepath to urlpath, and it is done. So for this example the correct result that will open a Voila dashboard directly via MyBinder is:

https://mybinder.org/v2/gh/fomightez/communication_voila/master?urlpath=%2Fvoila%2Frender%2Fscripts%2Fbasics.ipynb

Then you can paste the edited URL in your browser, hit return, and then it will launch directly to the Voila dashboard version of your page.
Of course, you’d need to do a similar edit in the code it makes for the markdown or rst version of the badge code to paste in your README, too.

When in doubt, the easiest thing to do is to find a launch binder badge that works to open the Voila render and use that as a pattern to hand edit the URL. The launch binder badge under the Voila logo here presently works and is probably the best basis as I suppose if anything changes it will by updated first and foremost.

1 Like

Wayne,
Voila, it Works! You’re the best!
Here is what this has all been for:


I plan to use this in an undergraduate biology course that I will be teaching this fall. It still needs a few refinements, but now I have all of the pieces in place.

Thanks again,
David

That came out great. Very cool simulation.

Thanks. With a little playing around, you can likely convince yourself that wearing face masks and staying further away from people are pretty good ideas.