About JupyterHub and JupyterLab dependencies

Hi,

I am currently working on on-prem JupyterHub with K8s following z2jh.

Currently, we are using JupyterHub 1.5.0 and JupyterLab 3.6.3.

My questions:

  • Why does JupyterLab image install/need jupyterhub package?
  • Why newer images of JupyterLab are not backward compatible with older versions of JupyterHub?

I tried to use a newer Docker image (Datascience notebook lab-4.1.4) for JupyterLab and got the following logs:

Entered start.sh with args: /opt/conda/bin/jupyter-labhub-ext.sh --ip=0.0.0.0 --port=52347 --SingleUserNotebookApp.default_url=/lab --debug 4863e322c5578fe4920424c71baa3d974b0b56113bb111808cd944145dae25a9
Running hooks in: /usr/local/bin/start-notebook.d as uid: 1000 gid: 100
Done running hooks in: /usr/local/bin/start-notebook.d
Running hooks in: /usr/local/bin/before-notebook.d as uid: 1000 gid: 100
Sourcing shell script: /usr/local/bin/before-notebook.d/10activate-conda-env.sh
Done running hooks in: /usr/local/bin/before-notebook.d
Executing the command: /opt/conda/bin/jupyter-labhub-ext.sh --ip=0.0.0.0 --port=52347 --SingleUserNotebookApp.default_url=/lab --debug 4863e322c5578fe4920424c71baa3d974b0b56113bb111808cd944145dae25a9
cp: cannot stat '/conf/*': No such file or directory
[I 2024-03-26 08:17:50.946 SingleUserLabApp mixins:547] Starting jupyterhub single-user server version 4.0.2
[I 2024-03-26 08:17:50.946 SingleUserLabApp mixins:561] Extending jupyterlab.labhubapp.SingleUserLabApp from jupyterlab 4.1.4
[I 2024-03-26 08:17:50.946 SingleUserLabApp mixins:561] Extending jupyter_server.serverapp.ServerApp from jupyter_server 2.13.0
[D 2024-03-26 08:17:50.956 SingleUserLabApp application:194] Searching ['/home/jovyan/.jupyter', '/home/jovyan/.local/etc/jupyter', '/opt/conda/etc/jupyter', '/usr/local/etc/jupyter', '/etc/jupyter'] for config files
[D 2024-03-26 08:17:50.957 SingleUserLabApp application:908] Looking for jupyter_config in /etc/jupyter
[D 2024-03-26 08:17:50.957 SingleUserLabApp application:908] Looking for jupyter_config in /usr/local/etc/jupyter
[D 2024-03-26 08:17:50.957 SingleUserLabApp application:908] Looking for jupyter_config in /opt/conda/etc/jupyter
[D 2024-03-26 08:17:50.957 SingleUserLabApp application:908] Looking for jupyter_config in /home/jovyan/.local/etc/jupyter
[D 2024-03-26 08:17:50.957 SingleUserLabApp application:908] Looking for jupyter_config in /home/jovyan/.jupyter
[D 2024-03-26 08:17:50.958 SingleUserLabApp application:908] Looking for jupyter_server_config in /etc/jupyter
[D 2024-03-26 08:17:50.959 SingleUserLabApp application:929] Loaded config file: /etc/jupyter/jupyter_server_config.py
[D 2024-03-26 08:17:50.959 SingleUserLabApp application:908] Looking for jupyter_server_config in /usr/local/etc/jupyter
[D 2024-03-26 08:17:50.959 SingleUserLabApp application:908] Looking for jupyter_server_config in /opt/conda/etc/jupyter
[D 2024-03-26 08:17:50.959 SingleUserLabApp application:908] Looking for jupyter_server_config in /home/jovyan/.local/etc/jupyter
[D 2024-03-26 08:17:50.959 SingleUserLabApp application:908] Looking for jupyter_server_config in /home/jovyan/.jupyter
[W 2024-03-26 08:17:50.960 SingleUserLabApp configurable:214] Config option `open_browser` not recognized by `SingleUserLabApp`.  Did you mean `browser`?
[I 2024-03-26 08:17:51.099 SingleUserLabApp manager:347] jupyter_lsp | extension was successfully linked.
[I 2024-03-26 08:17:51.099 SingleUserLabApp manager:347] jupyter_resource_usage | extension was successfully linked.
[D 2024-03-26 08:17:51.105 MathJaxExtension] Config changed: {'FileContentsManager': {'delete_to_trash': False}, 'SingleUserLabApp': {'ip': '0.0.0.0', 'port': 52347, 'log_level': 'DEBUG'}, 'SingleUserNotebookApp': {'default_url': '/lab'}, 'ExtensionApp': {'log_level': 'DEBUG'}, 'ServerApp': {'ip': '0.0.0.0', 'open_browser': False, 'jpserver_extensions': <LazyConfigValue {'update': {'jupyter_lsp': True, 'jupyter_resource_usage': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyter_server_terminals': True, 'jupyterlab': True, 'jupyterlab_git': True, 'nbclassic': True, 'nbdime': True, 'nbgitpuller': True, 'notebook': True, 'notebook_shim': True}}>}, 'InlineBackend': {'figure_formats': {'jpeg', 'png', 'svg', 'pdf'}}}
[W 2024-03-26 08:17:51.106 SingleUserLabApp configurable:214] Config option `open_browser` not recognized by `SingleUserLabApp`.  Did you mean `browser`?
[D 2024-03-26 08:17:51.106 SingleUserLabApp application:457] Config changed: {'FileContentsManager': {'delete_to_trash': False}, 'SingleUserLabApp': {'ip': '0.0.0.0', 'port': 52347, 'log_level': 'DEBUG'}, 'SingleUserNotebookApp': {'default_url': '/lab'}, 'ExtensionApp': {'log_level': 'DEBUG'}, 'ServerApp': {'ip': '0.0.0.0', 'open_browser': False, 'jpserver_extensions': <LazyConfigValue value={'jupyter_lsp': True, 'jupyter_resource_usage': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyter_server_terminals': True, 'jupyterlab': True, 'jupyterlab_git': True, 'nbclassic': True, 'nbdime': True, 'nbgitpuller': True, 'notebook': True, 'notebook_shim': True}>}, 'InlineBackend': {'figure_formats': {'jpeg', 'png', 'svg', 'pdf'}}}
[W 2024-03-26 08:17:51.107 SingleUserLabApp configurable:214] Config option `open_browser` not recognized by `SingleUserLabApp`.  Did you mean `browser`?
[I 2024-03-26 08:17:51.107 SingleUserLabApp manager:347] jupyter_server_mathjax | extension was successfully linked.
[I 2024-03-26 08:17:51.108 SingleUserLabApp manager:347] jupyter_server_proxy | extension was successfully linked.
[D 2024-03-26 08:17:51.112 TerminalsExtensionApp] Config changed: {'FileContentsManager': {'delete_to_trash': False}, 'SingleUserLabApp': {'ip': '0.0.0.0', 'port': 52347, 'log_level': 'DEBUG'}, 'SingleUserNotebookApp': {'default_url': '/lab'}, 'ExtensionApp': {'log_level': 'DEBUG'}, 'ServerApp': {'ip': '0.0.0.0', 'open_browser': False, 'jpserver_extensions': <LazyConfigValue value={'jupyter_lsp': True, 'jupyter_resource_usage': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyter_server_terminals': True, 'jupyterlab': True, 'jupyterlab_git': True, 'nbclassic': True, 'nbdime': True, 'nbgitpuller': True, 'notebook': True, 'notebook_shim': True}>}, 'InlineBackend': {'figure_formats': {'jpeg', 'png', 'svg', 'pdf'}}}
[W 2024-03-26 08:17:51.113 SingleUserLabApp configurable:214] Config option `open_browser` not recognized by `SingleUserLabApp`.  Did you mean `browser`?
[D 2024-03-26 08:17:51.113 SingleUserLabApp application:457] Config changed: {'FileContentsManager': {'delete_to_trash': False}, 'SingleUserLabApp': {'ip': '0.0.0.0', 'port': 52347, 'log_level': 'DEBUG'}, 'SingleUserNotebookApp': {'default_url': '/lab'}, 'ExtensionApp': {'log_level': 'DEBUG'}, 'ServerApp': {'ip': '0.0.0.0', 'open_browser': False, 'jpserver_extensions': <LazyConfigValue value={'jupyter_lsp': True, 'jupyter_resource_usage': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyter_server_terminals': True, 'jupyterlab': True, 'jupyterlab_git': True, 'nbclassic': True, 'nbdime': True, 'nbgitpuller': True, 'notebook': True, 'notebook_shim': True}>}, 'InlineBackend': {'figure_formats': {'jpeg', 'png', 'svg', 'pdf'}}}
[W 2024-03-26 08:17:51.114 SingleUserLabApp configurable:214] Config option `open_browser` not recognized by `SingleUserLabApp`.  Did you mean `browser`?
[I 2024-03-26 08:17:51.115 SingleUserLabApp manager:347] jupyter_server_terminals | extension was successfully linked.
[D 2024-03-26 08:17:51.120 LabApp] Config changed: {'NotebookApp': {}, 'ServerApp': {'ip': '0.0.0.0', 'open_browser': False, 'jpserver_extensions': <LazyConfigValue value={'jupyter_lsp': True, 'jupyter_resource_usage': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyter_server_terminals': True, 'jupyterlab': True, 'jupyterlab_git': True, 'nbclassic': True, 'nbdime': True, 'nbgitpuller': True, 'notebook': True, 'notebook_shim': True}>}, 'FileContentsManager': {'delete_to_trash': False}, 'SingleUserLabApp': {'ip': '0.0.0.0', 'port': 52347, 'log_level': 'DEBUG'}, 'SingleUserNotebookApp': {'default_url': '/lab'}, 'ExtensionApp': {'log_level': 'DEBUG'}, 'InlineBackend': {'figure_formats': {'jpeg', 'png', 'svg', 'pdf'}}}
[W 2024-03-26 08:17:51.121 SingleUserLabApp configurable:214] Config option `open_browser` not recognized by `SingleUserLabApp`.  Did you mean `browser`?
[I 2024-03-26 08:17:51.121 SingleUserLabApp manager:347] jupyterlab | extension was successfully linked.
[I 2024-03-26 08:17:51.121 SingleUserLabApp manager:347] jupyterlab_git | extension was successfully linked.
[D 2024-03-26 08:17:51.126 NotebookApp] Config changed: {'NotebookApp': {}, 'ServerApp': {'ip': '0.0.0.0', 'open_browser': False, 'jpserver_extensions': <LazyConfigValue value={'jupyter_lsp': True, 'jupyter_resource_usage': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyter_server_terminals': True, 'jupyterlab': True, 'jupyterlab_git': True, 'nbclassic': True, 'nbdime': True, 'nbgitpuller': True, 'notebook': True, 'notebook_shim': True}>}, 'FileContentsManager': {'delete_to_trash': False}, 'SingleUserLabApp': {'ip': '0.0.0.0', 'port': 52347, 'log_level': 'DEBUG'}, 'SingleUserNotebookApp': {'default_url': '/lab'}, 'ExtensionApp': {'log_level': 'DEBUG'}, 'InlineBackend': {'figure_formats': {'jpeg', 'png', 'svg', 'pdf'}}}
[W 2024-03-26 08:17:51.126 SingleUserLabApp configurable:214] Config option `open_browser` not recognized by `SingleUserLabApp`.  Did you mean `browser`?
[I 2024-03-26 08:17:51.127 SingleUserLabApp manager:347] nbclassic | extension was successfully linked.
[I 2024-03-26 08:17:51.127 SingleUserLabApp manager:347] nbdime | extension was successfully linked.
[I 2024-03-26 08:17:51.127 SingleUserLabApp manager:347] nbgitpuller | extension was successfully linked.
[D 2024-03-26 08:17:51.132 JupyterNotebookApp] Config changed: {'NotebookApp': {}, 'ServerApp': {'ip': '0.0.0.0', 'open_browser': False, 'jpserver_extensions': <LazyConfigValue value={'jupyter_lsp': True, 'jupyter_resource_usage': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyter_server_terminals': True, 'jupyterlab': True, 'jupyterlab_git': True, 'nbclassic': True, 'nbdime': True, 'nbgitpuller': True, 'notebook': True, 'notebook_shim': True}>}, 'FileContentsManager': {'delete_to_trash': False}, 'SingleUserLabApp': {'ip': '0.0.0.0', 'port': 52347, 'log_level': 'DEBUG'}, 'SingleUserNotebookApp': {'default_url': '/lab'}, 'ExtensionApp': {'log_level': 'DEBUG'}, 'InlineBackend': {'figure_formats': {'jpeg', 'png', 'svg', 'pdf'}}}
[W 2024-03-26 08:17:51.133 SingleUserLabApp configurable:214] Config option `open_browser` not recognized by `SingleUserLabApp`.  Did you mean `browser`?
[I 2024-03-26 08:17:51.133 SingleUserLabApp manager:347] notebook | extension was successfully linked.
[I 2024-03-26 08:17:51.446 SingleUserLabApp manager:347] notebook_shim | extension was successfully linked.
[W 2024-03-26 08:17:51.452 SingleUserLabApp serverapp:2106] Customizing authentication via ServerApp.login_handler_class=<class 'jupyterhub.singleuser.mixins.make_singleuser_app.<locals>.JupyterHubLoginHandler'> is deprecated in Jupyter Server 2.0. Use ServerApp.identity_provider_class. Falling back on legacy authentication.
/opt/conda/lib/python3.11/site-packages/jupyter_server/serverapp.py:2235: JupyterServerAuthWarning: Core endpoints without @allow_unauthenticated, @ws_authenticated, nor @web.authenticated:
- GET of JupyterHubLogoutHandler registered for /user/username/logout
  self.web_app = ServerWebApplication(
[I 2024-03-26 08:17:51.468 SingleUserLabApp manager:367] notebook_shim | extension was successfully loaded.
[D 2024-03-26 08:17:51.470 SingleUserLabApp serverextension:65] [lsp] rootUri will be file:///home/jovyan
[D 2024-03-26 08:17:51.471 SingleUserLabApp serverextension:69] [lsp] virtualDocumentsUri will be file:///home/jovyan/.virtual_documents
[I 2024-03-26 08:17:51.471 SingleUserLabApp manager:367] jupyter_lsp | extension was successfully loaded.
[I 2024-03-26 08:17:51.472 SingleUserLabApp manager:367] jupyter_resource_usage | extension was successfully loaded.
[I 2024-03-26 08:17:51.472 SingleUserLabApp manager:367] jupyter_server_mathjax | extension was successfully loaded.
[D 2024-03-26 08:17:51.487 SingleUserLabApp __init__:75] [jupyter-server-proxy] Started with known servers: pluto
[I 2024-03-26 08:17:51.488 SingleUserLabApp manager:367] jupyter_server_proxy | extension was successfully loaded.
[I 2024-03-26 08:17:51.489 SingleUserLabApp manager:367] jupyter_server_terminals | extension was successfully loaded.
[I 2024-03-26 08:17:51.492 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.11/site-packages/jupyterlab
[I 2024-03-26 08:17:51.492 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 2024-03-26 08:17:51.493 LabApp] Extension Manager is 'pypi'.
[D 2024-03-26 08:17:51.493 LabApp] Plugins in PyPIExtensionManager will managed on the sys_prefix level
[D 2024-03-26 08:17:51.497 LabApp] Extensions list will be fetched from https://pypi.org/pypi.
[I 2024-03-26 08:17:51.497 LabApp] Extensions will be fetched using proxy, proxy host and port: ('proxy', '8080')
[D 2024-03-26 08:17:51.497 LabApp] Plugins in PluginManager will managed on the sys_prefix level
[I 2024-03-26 08:17:51.499 SingleUserLabApp manager:367] jupyterlab | extension was successfully loaded.
[I 2024-03-26 08:17:51.504 SingleUserLabApp manager:367] jupyterlab_git | extension was successfully loaded.
[I 2024-03-26 08:17:51.508 SingleUserLabApp manager:367] nbclassic | extension was successfully loaded.
[I 2024-03-26 08:17:51.569 SingleUserLabApp manager:367] nbdime | extension was successfully loaded.
[I 2024-03-26 08:17:51.569 SingleUserLabApp manager:367] nbgitpuller | extension was successfully loaded.
[I 2024-03-26 08:17:51.574 SingleUserLabApp manager:367] notebook | extension was successfully loaded.

  _   _          _      _
 | | | |_ __  __| |__ _| |_ ___
 | |_| | '_ \/ _` / _` |  _/ -_)
  \___/| .__/\__,_\__,_|\__\___|
       |_|
                                                                           
Read the migration plan to Notebook 7 to learn about the new features and the actions to take if you are using extensions.

https://jupyter-notebook.readthedocs.io/en/latest/migrate_to_notebook7.html

Please note that updating to Notebook 7 might break some of your extensions.

Traceback (most recent call last):
  File "/opt/conda/lib/python3.11/site-packages/traitlets/utils/importstring.py", line 35, in import_item
    pak = getattr(module, obj)
          ^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'notebook.base.handlers' has no attribute 'IPythonHandler'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/conda/bin/jupyter-labhub", line 10, in <module>
    sys.exit(main())
             ^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/jupyterlab/labhubapp.py", line 41, in main
    return SingleUserLabApp.launch_instance(argv)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/jupyter_core/application.py", line 283, in launch_instance
    super().launch_instance(argv=argv, **kwargs)
  File "/opt/conda/lib/python3.11/site-packages/traitlets/config/application.py", line 1074, in launch_instance
    app.initialize(argv)
  File "/opt/conda/lib/python3.11/site-packages/jupyterhub/singleuser/mixins.py", line 955, in initialize
    _patch_app_base_handlers(self)
  File "/opt/conda/lib/python3.11/site-packages/jupyterhub/singleuser/mixins.py", line 866, in _patch_app_base_handlers
    base_handlers.append(import_item(base_handler_name))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/conda/lib/python3.11/site-packages/traitlets/utils/importstring.py", line 37, in import_item
    raise ImportError("No module named %s" % obj) from e
ImportError: No module named IPythonHandler
[D 2024-03-26 08:17:52.155 SingleUserLabApp types:223] Checking for /home/jovyan/node_modules/bash-language-server/out/cli.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/share/jupyter/lab/staging/node_modules/bash-language-server/out/cli.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/lib/node_modules/bash-language-server/out/cli.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/node_modules/bash-language-server/out/cli.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/lib/node_modules/bash-language-server/out/cli.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/node_modules/bash-language-server/out/cli.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:229] bash-language-server/out/cli.js not found in node_modules of [PosixPath('/home/jovyan'), PosixPath('/opt/conda/share/jupyter/lab/staging'), PosixPath('/opt/conda/lib'), PosixPath('/opt/conda'), PosixPath('/opt/conda/lib'), PosixPath('/opt/conda')]
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /home/jovyan/node_modules/bash-language-server/bin/main.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/share/jupyter/lab/staging/node_modules/bash-language-server/bin/main.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/lib/node_modules/bash-language-server/bin/main.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/node_modules/bash-language-server/bin/main.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/lib/node_modules/bash-language-server/bin/main.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:223] Checking for /opt/conda/node_modules/bash-language-server/bin/main.js
[D 2024-03-26 08:17:52.156 SingleUserLabApp types:229] bash-language-server/bin/main.js not found in node_modules of [PosixPath('/home/jovyan'), PosixPath('/opt/conda/share/jupyter/lab/staging'), PosixPath('/opt/conda/lib'), PosixPath('/opt/conda'), PosixPath('/opt/conda/lib'), PosixPath('/opt/conda')]
[D 2024-03-26 08:17:52.157 SingleUserLabApp types:223] Checking for /home/jovyan/node_modules/dockerfile-language-server-nodejs/lib/server.js
  • Why does JupyterLab image install/need jupyterhub package?

JupyterHub is a single Python package, providing two components:

  1. the JupyterHub server (usually called the Hub)
  2. the JupyterHub authentication extension (an Extension for jupyter-server for authenticating with the Hub)

It’s the second component that you need in the user environment.

These are tightly coupled, so developed and distributed as a single package. They could be two, but the only problem that would really solve is a wasted dependency on sqlalchemy, while complicating distribution substantially.

  • Why newer images of JupyterLab are not backward compatible with older versions of JupyterHub?

They usually are a pretty long way, but not forever. 1.5 is very far out of date - 3 years and 3 major versions behind. Hopefully the first bit explains why - the mechanism for authenticating with JupyterHub is provided by the JupyterHub package in the user environment. This should ideally match, but as long as the major version matches, it should work.

I believe the specific bug you hit is fixed in jupyterhub 4.1, which is in the lab-4.1.5 image.

Thanks for the explanation.

We just tested and JupyterHub 1.5.0 works with lab-4.1.5 images which contains jupyterhub-4.1.1. Thanks again for the bug fix.