Is it possible to deploy and run Panel apps via Jupyter Hub?

Is it possible to deploy and run Panel apps via Jupyter Hub?

I’m thinking that it is a major advantage of Voila that they have the Jupyter Hub. If Panel could run there as well then there would be more freedom to choose one or the other depending on use case and preferences.

I know there are attempts for Streamlit. See https://discuss.streamlit.io/t/jupyterhub-streamlit/1238/5

@philippjfr provided this link check out https://github.com/holoviz/jupyter-panel-proxy

I believe but do not know that this is something to install on a Jupyter Server and then it works.

Hi @Marc, here is an example of a PR that switches to using jupyter-panel-proxy: https://github.com/pyviz-demos/glaciers/pull/11. Basically if you include jupyter-panel-proxy in your environment.yaml or requirements.txt, then you should be able to access any panel app at the endpoint <jupyter_url>/panel/<filename>.

1 Like

This “launch app” approach using jupyter-panel-proxy was working great for me over at


(see the binder links in the readme)
and I was going to tweet about jupyter-panel-proxy because it seems not many people know about it.

But then I forced binder to rebuild my environment and now I just get a blank page.
No errors, just no app displayed.

Is there something introduced in Panel or other Holoviz tools in the last 4 months that I now need to handle in my code if I want the app displayed?

It seems like something about the app is broken since it does seem to launch a session. Do you know of a way to view the logs for the session?

I tried simplifying and running locally.

  1. Created environment:
conda create -n panel -c conda-forge  jupyter-panel-proxy  jupyter
  1. Created simple panel_test.ipynb notebook:
import panel as pn
pn.extension()
def f(x):
    return x
pn.interact(f, x=10)
  1. Fired up jupyter:
conda activate panel
jupyter notebook
  1. made sure the notebook ran (it did)
  2. tried running as panel app using
    http://localhost:8888/panel/panel_test.ipynb
    which gives a 500 error, with this info:
[E 15:53:28.975 NotebookApp] Uncaught exception GET /panel/panel_test.ipynb (::1)
    HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/panel/panel_test.ipynb', version='HTTP/1.1', remote_ip='::1')
    Traceback (most recent call last):
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\site-packages\tornado\web.py", line 1699, in _execute
        result = await result
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\site-packages\jupyter_server_proxy\websocket.py", line 96, in get
        return await self.http_get(*args, **kwargs)
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\site-packages\jupyter_server_proxy\handlers.py", line 507, in http_get
        return await self.proxy(self.port, path)
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\site-packages\jupyter_server_proxy\handlers.py", line 501, in proxy
        await self.ensure_process()
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\site-packages\jupyter_server_proxy\handlers.py", line 478, in ensure_process
        await proc.start()
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\site-packages\simpervisor\process.py", line 91, in start
        *self._proc_args, **self._proc_kwargs
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\asyncio\subprocess.py", line 217, in create_subprocess_exec
        stderr=stderr, **kwds)
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\asyncio\base_events.py", line 1540, in subprocess_exec
        bufsize, **kwargs)
      File "C:\Users\rsignell\miniconda3\envs\panel\lib\asyncio\base_events.py", line 462, in _make_subprocess_transport
        raise NotImplementedError
    NotImplementedError
[E 15:53:28.991 NotebookApp] {
      "Host": "localhost:8888",
      "Connection": "keep-alive",
      "Upgrade-Insecure-Requests": "1",
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36",
      "Sec-Fetch-Dest": "document",
      "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
      "Sec-Fetch-Site": "none",
      "Sec-Fetch-Mode": "navigate",
      "Sec-Fetch-User": "?1",
      "Accept-Encoding": "gzip, deflate, br",
      "Accept-Language": "en-US,en;q=0.9",
      "Cookie": "_xsrf=2|9ab95683|e2696d1d58bccdc163aea89ed6061d06|1581373315; username-localhost-8888=\"2|1:0|10:1583268754|23:username-localhost-8888|44:M2VmNjI1YTYyYWY0NGQwYTgzNzVhZjNmZDEwMTI3ZTI=|9240f4de1e7dd50d628fa09d68d323053cf4a69e6f81ad8b980c506d5a16fcd0\""
    }

I hope that’s enough to give some clues…

1 Like

@philippjfr, I’m wondering if this issue might not actually be something holoviz or panel related. Should I be raising this issue on jupyter-server-proxy or something?

Thanks for the detailed example. Very unclear to me what the problem there is. It also seems somewhat unlikely to me that’s the same error we were seeing on MyBinder since it does seem to start the server correctly. Filing an issue with jupyter-server-proxy could definitely be helpful though since they might have a better idea on how to debug this.

I didn’t post it there yet. But I did discover something. This binder link works perfectly:
https://aws-uswest2-binder.pangeo.io/v2/gh/reproducible-notebooks/HRRR_Dashboard/pinned?urlpath=panel/HRRR_Dashboard

Producing:

So it works using this old pinned environment.

But it doesn’t work (yet) with this unpinned, up-to-date environment

I tried getting it up and running on Kubeflow’s Jupyterhub but without luck. For reference I’ve opened an issue here https://github.com/kubeflow/kubeflow/issues/5194