I’m increasingly using Voila as a means to enable complex data analysis for a set of users at work. At the moment the typical interaction follows this path:
Capture a set of business identifiers from the user via IPython widgets
Load up a custom dataset based on those identifiers
Perform analysis as requested based on further user input (e.g. button presses)
Ideally I would like to be able to bypass the first stage here by having identifiers passed into the Voila notebook as part of the URI. This would allow the notebook to ‘pre-populate’ based on calls from other related Voila notebooks, or even other systems.
In other web environments my go-to approach would be to embed the identifiers in the query string part of the URI. I’ve searched extensively for ways to access this information in a Voila context but I keep hitting dead ends. I’ve seen discussions of: parts of the URI being added to the environment variables (a bit like a CGI script), using “prelaunch hooks” to make the information available or using the javascript ‘kernel.execute’ method to pass the data back from the front end. None of these seem to work for me, for a variety of reasons - I’m guessing partly (or completely) to do with my own ignorance (for which I apologise).
Does anyone know of a reliable method of getting hold of the query string information in a Voila notebook? If so could you share some minimal code demonstrating how to make it work? I’d prefer something that works with ‘vanilla’ Voila but I can probably persuade my Jupyter sysadmin to help me out if server-side tweaks are required.
Thanks for the responses @fomightez - these links quickly lead me to conversations that I picked up in my prior research. That said the distinction between the spawner and the notebook is not one I had considered. Sorry to confess that I don’t know a huge amount about the spawner, but if that offered some route to feed the parameters into a notebook I’d be very happy to work with it as the starting point.
The picture that seems to be emerging is that there’s quite a bit of interest on the “notebook builder” side (i.e. others like me) to have this capability, and a decent amount of support from the Jupyter devs for this, but that no clear path has emerged to actually get it implemented. That might be a misreading of the dynamics of the discussions I have read - can anyone closer to it comment? I’m new to the community so trying to tread carefully!!
In case it helps anyone, I wasn’t having much luck using that notebook that ConorMc posted above, and so I reworked it to step through much what I think it was trying to demonstrate in a manner that works via MyBinder.org launches. Major caveat: works as a notebook; the javascript cell to get the full URL won’t work in Voila (see below).
The reason the approach used in the notebook fails in Voila is two-fold. The way the javascript is run with the %%javascript cell magic in the notebook I posted is not compatible with Voila. However, just because that route to run javascript doesn’t work in Voila, it doesn’t mean you cannot run javascript in code for Voila. Using Javascript imported from IPython.display you can use javascript in Voila if you use the right syntax to place the javascript code in the display(Javascript()). For example, the following will work in Voila to trigger javascript to display an alert window in Voila:
#based on https://github.com/voila-dashboards/voila/issues/743
from IPython.display import Javascript
display(Javascript('''alert("test")'''))
However, even though other javascript works, I’ve been unable to get the command IPython.notebook.kernel.execute() to work in Voila. That is used in the notebook example to pass via javascript the string collected from the URL location into the notebook kernel. I don’t see how to pass that to Voila from javascript though. I don’t think getting IPython.notebook.kernel.execute() working is just a matter of not nesting it correctly in the right combination of quotes; however, there’s a slim chance I haven’t quite worked this out.
UPDATE: This is how to use the notebook that ConorMc posted above with MyBinder to demonstrate the Voila-compatible way to access a query string inside Voila. (Bonus is that it demonstrates a Voila-compatible way of getting the full URL for when running in MyBinder, too.)
Step-by-step:
Launch a binder session with Voila installed and slightly edited version of the notebook ConorMc posted above present by clicking here.
When the session spins up and the demo notebook opens, you’ll notice the content of the notebook includes code setting ‘Kim’ as the username around the middle.
Launch the Voila version of this notebook by pressing ‘Voila’ button from the toolbar.
Voila will open and it will say Hi Kim towards the bottom of the content on the page.
Now to see the passing of the username query string in action, click on the blue link at the bottom that says ‘Link to myself as user Riley’. It should open another tab with Voila again.
Note that this new tab will include ?username=Riley at the end of the URL. The content of the Voila page itself will look different now, too: it will say ‘Hi Riley’ in place of ‘Hi Kim’ because this Voila instance has been passed a username via the URL.
You can see all the envs environment variables that the JupyterHub exposes to Voila by adding the following code to a cell in that demonstration notebook, saving the notebook, and launching Voila via the button on the toolbar.
import os
envs = {k: v for k, v in os.environ.items()}
display (envs)
(Worked out from re-reading first link I posted in this thread and looking over the reference to the implementation therein, in particular, to here. I was too focused on the way I had been using javascript and missing some things. It was key to delete ‘localhost’ in the last cell with code in it in order to use the notebook that ConorMc posted above with MyBinder.)