# Method to access query string in Voila notebook

**URL:** <https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387>\
**Category:** General\
**Created:** [July 27, 2020, 11:37am UTC](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387 "2020-07-27T11:37:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ConorMc](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/conormc/32/2471_2.png) [@ConorMc](https://discourse.jupyter.org/u/ConorMc)\
**Post date:** [July 27, 2020, 11:37am UTC](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/1 "2020-07-27T11:37:54Z")

</div>

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.

Many thanks  
Conor

---

<div class="post-metadata">

**Author:** ![fomightez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/fomightez/32/495_2.png) [@fomightez](https://discourse.jupyter.org/u/fomightez)\
**Post date:** [July 27, 2020, 2:44pm UTC](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/2 "2020-07-27T14:44:11Z")

</div>

I don’t have specifics or what is the best current way to pass variables via the URI but I did come across these:

> <https://github.com/voila-dashboards/voila/issues/105>
>
> We could specify the template name through a URL parameter.

> [@Pass parameters to a notebook on jupyterhub/binderhub](https://discourse.jupyter.org/t/pass-parameters-to-a-notebook-on-jupyterhub-binderhub/1973/2):
>
> There is a bunch of thoughts on a related but different topic in [https://github.com/jupyterhub/binderhub/issues/712](https://github.com/jupyterhub/binderhub/issues/712) which also has a lot of links/issues referring to it. If I understand you correctly you want to add parameters for the notebook, not the spawner (or BinderHub itself). This is what makes it a bit different from the issue I linked. There are (at least?) two things to solve: recognise that the query parameters aren’t meant for the spawner and pass them on use a notebook to extrac…

---

<div class="post-metadata">

**Author:** ![ConorMc](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/conormc/32/2471_2.png) [@ConorMc](https://discourse.jupyter.org/u/ConorMc)\
**Post date:** [July 27, 2020, 5:22pm UTC](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/3 "2020-07-27T17:22:54Z")

</div>

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!!

---

<div class="post-metadata">

**Author:** ![ConorMc](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/conormc/32/2471_2.png) [@ConorMc](https://discourse.jupyter.org/u/ConorMc)\
**Post date:** [October 15, 2020, 7:04am UTC](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/4 "2020-10-15T07:04:51Z")

</div>

This looks to be code doing exactly what I want:

> <https://github.com/voila-dashboards/voila/blob/b003a7fc62023e5b4c8dab7dd64b94a920610c15/notebooks/query-strings.ipynb>

It needs Voila 0.2+.

---

<div class="post-metadata">

**Author:** ![joseberlines](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/joseberlines/32/3064_2.png) [@joseberlines](https://discourse.jupyter.org/u/joseberlines)\
**Post date:** [January 4, 2022, 11:12am UTC](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/5 "2022-01-04T11:12:48Z")

</div>

Is this issue/question still “alive”?  
I added this issue in github/jupyterhub:

> <https://github.com/jupyterhub/jupyterhub/issues/3753>
>
> Problem:
> When rendering a notebook with voila in a JupyterHub environement we a…re parsing the URL in order to pass default variables into the rendered notebook, including for example "autorun=True that fires (autoclick) some of the buttons. This allows for opening and rendering notebooks from other notebooks and run them practically on the fly.
> 
> Use case:
> When designing a GUI in a notebook with ipywidgets (@jasongrout https://github.com/jupyter-widgets/ipywidgets) or ipyvuetify (@mariobuikhuizen https://github.com/mariobuikhuizen/ipyvuetify) it is oftentimes very interesting to pass default variables into the URL to fill in default values into input text widgets or checkboxes or whatever input fields, including the possibility of passing variables that will automatically click and fire a particular process. This allows for dashboards with buttons that render instances of other notebooks in new tabs of the browser following user interactions with a notebook. This issue is also very much related to voila (@jtpio in https://github.com/voila-dashboards/voila).
> This is a use case that somehow looks to me very normal but I dont know exactly in with which one of the mentioned repos is related.
> 
> Solution right now:
> The solution entails the use of the following code:
> \`\`\`
> from urllib.parse import urlparse, parse\_qs
> import os    
> URL\_BASE = os.environ.get('SCRIPT\_NAME')
> PARAMETERS = os.environ.get("QUERY\_STRING")
> print(f'{URL\_BASE=}')
> print(f'{PARAMETERS=}')
> captured\_values = parse\_qs(PARAMETERS)
> print('here parse\_qs of query:',captured\_values)
> \`\`\`
> 
> Is this the way it is supposed to be done? Is there a more Jupyter way to do it?
> This approach has a problem, os.environ does not seem to offer the possibility to query the fragment of the url after the symbol #
> See stackoverflow: 
> https://stackoverflow.com/questions/70423180/python-getting-the-complete-url-with-os-environ
> 
> I have been reading quite a bit about this in different issues of voila & JupyterHub:
> https://github.com/voila-dashboards/voila/issues/410#issue-504866187
> https://discourse.jupyter.org/t/automatically-loading-external-data-into-jupyterhub-instances/5502
> https://github.com/voila-dashboards/voila/pull/201
> https://github.com/voila-dashboards/voila/pull/835
> 
> Somehow all those solutions/proposals/discussions do not seem to have a clear single most recommended solution for accesing the URL parameters in the context of a jupyterHub solution running in house (not using Binder).
> 
> \### Proposed change
> Add to the documentation of jupyterLab a recommended way to access all the parameters of an URL, iincluding the so called "fragment", i.e. parameters of the url after the # symbol
> 
> \### Alternative options
> Instead of os.environ other possibility is using the cgi module. Somehow I was not able to parse the complete URL but it seems to be possible and preferred by some people (
> 
> 
> \### Who would use this feature?
> This feature/solution would be used by a community coding in a jupyter Hub server based in house solution where different users rendered notebooks of other users passing personal parameters (for instance the name of a document to be accessed in a database)
> 
> 
> \### (Optional): Suggest a solution
> The solution ideally should not involve hacking around with jupyter Lab or extensions in Jupyter Hub since so far the users do not have the rights to install extensions, and the amount and different kind of parameters depends very much on the use case.

I still dont find a clear method to access the query string in voila notebook anywhere.

---

<div class="post-metadata">

**Author:** ![fomightez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/fomightez/32/495_2.png) [@fomightez](https://discourse.jupyter.org/u/fomightez)\
**Post date:** [January 4, 2022, 10:18pm UTC](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/6 "2022-01-04T22:18:14Z")

</div>

In case it helps anyone, I wasn’t having much luck using that [notebook that ConorMc posted above](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/4), 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](http://MyBinder.org) launches. **Major caveat: works as a notebook;** the javascript cell to get the full URL **won’t work in Voila** (see below).

> <https://gist.github.com/fomightez/3ff6d30085720cdf8b7e0acac298e146>

[passing full URL to Python via query string demonstrated via mybinder.org](https://gist.github.com/fomightez/3ff6d30085720cdf8b7e0acac298e146)

* * *

* * *

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:

```python
#based on https://github.com/voila-dashboards/voila/issues/743
from IPython.display import Javascript
display(Javascript('''alert("test")'''))

```

See other examples [here](https://github.com/voila-dashboards/voila/issues/743) and [here](https://stackoverflow.com/a/64460485/8508004).

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.

---

<div class="post-metadata">

**Author:** ![fomightez](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/fomightez/32/495_2.png) [@fomightez](https://discourse.jupyter.org/u/fomightez)\
**Post date:** [February 9, 2022, 5:47am UTC](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/7 "2022-02-09T05:47:31Z")

</div>

**UPDATE** : This is how to use [the notebook that ConorMc posted above](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/4) 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:

1. Launch a binder session with Voila installed and _slightly edited version_ of the notebook ConorMc posted above present by clicking [here](https://mybinder.org/v2/gh/fomightez/communication_voila/master?filepath=query-strings.ipynb).

2. 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.

3. Launch the Voila version of this notebook by pressing ‘Voila’ button from the toolbar.

4. Voila will open and it will say `Hi Kim` towards the bottom of the content on the page.

5. 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.

6. 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.

```python
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](https://github.com/voila-dashboards/voila/blob/b003a7fc62023e5b4c8dab7dd64b94a920610c15/notebooks/query-strings.ipynb). 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](https://discourse.jupyter.org/t/method-to-access-query-string-in-voila-notebook/5387/4) with MyBinder.)
