Don't start JupyterLab if configuration is invalid

Viewed 600

When JupyterLab tries to start, in some occasions, the config file may be invalid, and Jupyterlab starts regardless in default port 8888.

Currently I have a JupyterLab service defined as follows, but I also try to start it manually and got the same results. An example when config file may be invalid is when a library is not available to be imported. I want to prevent Jupyter to start and fail gracefully.

[Unit]
Description=Jupyter Service

[Service]
Type=simple
PIDFile=/run/jupyter.pid
ExecStart=/bin/bash --login -c '/opt/conda/bin/jupyter lab --config=/home/jupyter/.jupyter/jupyter_notebook_config.py'
User=jupyter
Group=jupyter
WorkingDirectory=/home/jupyter
Restart=no

[Install]
WantedBy=multi-user.target
(base) root@ab-test1:/home/jupyter/.jupyter# service jupyter status
● jupyter.service - Jupyter Notebook Service
   Loaded: loaded (/lib/systemd/system/jupyter.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2022-02-02 07:53:24 UTC; 3s ago
 Main PID: 335 (jupyter-lab)
    Tasks: 1 (limit: 4915)
   Memory: 64.0M (high: 14.3G max: 14.3G)
   CGroup: /system.slice/jupyter.service
           └─335 /opt/conda/bin/python3.7 /opt/conda/bin/jupyter-lab --config=/home/jupyter/.jupyter/jupyter_notebook_config.py

Feb 02 07:53:27 ab-test1 bash[335]:     Traceback (most recent call last):
Feb 02 07:53:27 ab-test1 bash[335]:       File "/opt/conda/lib/python3.7/site-packages/traitlets/config/application.py", line 738, in _load_config_files
Feb 02 07:53:27 ab-test1 bash[335]:         config = loader.load_config()
Feb 02 07:53:27 ab-test1 bash[335]:       File "/opt/conda/lib/python3.7/site-packages/traitlets/config/loader.py", line 614, in load_config
Feb 02 07:53:27 ab-test1 bash[335]:         self._read_file_as_dict()
Feb 02 07:53:27 ab-test1 bash[335]:       File "/opt/conda/lib/python3.7/site-packages/traitlets/config/loader.py", line 646, in _read_file_as_dict
Feb 02 07:53:27 ab-test1 bash[335]:         exec(compile(f.read(), conf_filename, 'exec'), namespace, namespace)
Feb 02 07:53:27 ab-test1 bash[335]:       File "/home/jupyter/.jupyter/jupyter_notebook_config.py", line 3, in <module>
Feb 02 07:53:27 ab-test1 bash[335]:         import tensorflow
Feb 02 07:53:27 ab-test1 bash[335]:     ModuleNotFoundError: No module named 'tensorflow'
(base) root@ab-test1:/home/jupyter/.jupyter# service jupyter status
● jupyter.service - Jupyter Notebook Service
   Loaded: loaded (/lib/systemd/system/jupyter.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2022-02-02 07:53:24 UTC; 6s ago
 Main PID: 335 (jupyter-lab)
    Tasks: 2 (limit: 4915)
   Memory: 138.6M (high: 14.3G max: 14.3G)
   CGroup: /system.slice/jupyter.service
           └─335 /opt/conda/bin/python3.7 /opt/conda/bin/jupyter-lab --config=/home/jupyter/.jupyter/jupyter_notebook_config.py

Feb 02 07:53:29 ab-test1 bash[335]: [I 2022-02-02 07:53:29.644 ServerApp]  or http://127.0.0.1:8888/lab?token=ead21ce39f979fe916e7e041134da576feb28b839bd99577
Feb 02 07:53:29 ab-test1 bash[335]: [I 2022-02-02 07:53:29.644 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation)
Feb 02 07:53:29 ab-test1 bash[335]: [W 2022-02-02 07:53:29.648 ServerApp] No web browser found: could not locate runnable browser.
Feb 02 07:53:29 ab-test1 bash[335]: [C 2022-02-02 07:53:29.648 ServerApp]
Feb 02 07:53:29 ab-test1 bash[335]:     
Feb 02 07:53:29 ab-test1 bash[335]:     To access the server, open this file in a browser:
Feb 02 07:53:29 ab-test1 bash[335]:         file:///home/jupyter/.local/share/jupyter/runtime/jpserver-335-open.html
Feb 02 07:53:29 ab-test1 bash[335]:     Or copy and paste one of these URLs:
Feb 02 07:53:29 ab-test1 bash[335]:         http://localhost:8888/lab?token=ead21ce39f979fe916e7e041134da576feb28b839bd99577
Feb 02 07:53:29 ab-test1 bash[335]:      or http://127.0.0.1:8888/lab?token=ead21ce39f979fe916e7e041134da576feb28b839bd99577

Logs:

/opt/conda/bin/jupyter-lab --debug --config=/home/jupyter/.jupyter/jupyter_notebook_config.py
[D 2022-02-02 08:09:28.170 ServerApp] Searching ['/home/gogasca', '/home/gogasca/.jupyter', '/home/gogasca/.local/etc/jupyter', '/opt/conda/etc/jupyter', '/usr/local/etc/jupyter', '/etc/jupyter'] for config files
[D 2022-02-02 08:09:28.170 ServerApp] Looking for jupyter_config in /etc/jupyter
[D 2022-02-02 08:09:28.170 ServerApp] Looking for jupyter_config in /usr/local/etc/jupyter
[D 2022-02-02 08:09:28.170 ServerApp] Looking for jupyter_config in /opt/conda/etc/jupyter
[D 2022-02-02 08:09:28.171 ServerApp] Loaded config file: /opt/conda/etc/jupyter/jupyter_config.json
[D 2022-02-02 08:09:28.171 ServerApp] Looking for jupyter_config in /home/gogasca/.local/etc/jupyter
[D 2022-02-02 08:09:28.171 ServerApp] Looking for jupyter_config in /home/gogasca/.jupyter
[D 2022-02-02 08:09:28.171 ServerApp] Looking for jupyter_config in /home/gogasca
[D 2022-02-02 08:09:28.173 ServerApp] Looking for jupyter_notebook_config in /home/jupyter/.jupyter
[E 2022-02-02 08:09:28.174 ServerApp] Exception while loading config file /home/jupyter/.jupyter/jupyter_notebook_config.py
    Traceback (most recent call last):
      File "/opt/conda/lib/python3.7/site-packages/traitlets/config/application.py", line 738, in _load_config_files
        config = loader.load_config()
      File "/opt/conda/lib/python3.7/site-packages/traitlets/config/loader.py", line 614, in load_config
        self._read_file_as_dict()
      File "/opt/conda/lib/python3.7/site-packages/traitlets/config/loader.py", line 646, in _read_file_as_dict
        exec(compile(f.read(), conf_filename, 'exec'), namespace, namespace)
      File "/home/jupyter/.jupyter/jupyter_notebook_config.py", line 3, in <module>
        import tensorflow
    ModuleNotFoundError: No module named 'tensorflow'
[D 2022-02-02 08:09:28.177 ServerApp] Paths used for configuration of jupyter_server_config: 
        /etc/jupyter/jupyter_server_config.json
[D 2022-02-02 08:09:28.178 ServerApp] Paths used for configuration of jupyter_server_config: 
        /usr/local/etc/jupyter/jupyter_server_config.json
[D 2022-02-02 08:09:28.178 ServerApp] Paths used for configuration of jupyter_server_config: 
        /opt/conda/etc/jupyter/jupyter_server_config.d/beatrix_jupyterlab.json
        /opt/conda/etc/jupyter/jupyter_server_config.d/jupyter-server-proxy-jupyterserverextension.json
        /opt/conda/etc/jupyter/jupyter_server_config.d/jupyter_server_mathjax.json
        /opt/conda/etc/jupyter/jupyter_server_config.d/jupyterlab.json
        /opt/conda/etc/jupyter/jupyter_server_config.d/jupyterlab_git.json
        /opt/conda/etc/jupyter/jupyter_server_config.d/jupytext.json
        /opt/conda/etc/jupyter/jupyter_server_config.d/nbclassic.json
        /opt/conda/etc/jupyter/jupyter_server_config.d/nbdime.json
        /opt/conda/etc/jupyter/jupyter_server_config.json
[D 2022-02-02 08:09:28.179 ServerApp] Paths used for configuration of jupyter_server_config: 
        /home/gogasca/.local/etc/jupyter/jupyter_server_config.json
[D 2022-02-02 08:09:28.180 ServerApp] Paths used for configuration of jupyter_server_config: 
        /home/gogasca/.jupyter/jupyter_server_config.json
generated new fontManager
/opt/conda/lib/python3.7/site-packages/jupyter_server_mathjax/app.py:40: FutureWarning: The alias `_()` will be deprecated. Use `_i18n()` instead.
  help=_("""The MathJax.js configuration file that is to be used."""),
[I 2022-02-02 08:09:32.735 ServerApp] beatrix_jupyterlab | extension was successfully linked.
[W 2022-02-02 08:09:32.737 MathJaxExtension] Config option `kernel_spec_manager_class` not recognized by `MathJaxExtension`.
[W 2022-02-02 08:09:32.738 MathJaxExtension] Config option `kernel_spec_manager_class` not recognized by `MathJaxExtension`.
[W 2022-02-02 08:09:32.743 MathJaxExtension] Config option `kernel_spec_manager_class` not recognized by `MathJaxExtension`.
[D 2022-02-02 08:09:32.744 MathJaxExtension] Config changed: {'JupyterApp': {'kernel_spec_manager_class': 'nb_conda_kernels.CondaKernelSpecManager'}, 'ServerApp': {'config_file': '/home/jupyter/.jupyter/jupyter_notebook_config.py', 'log_level': 'DEBUG', 'jpserver_extensions': <LazyConfigValue {'update': {'beatrix_jupyterlab': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyterlab_git': True, 'jupytext': True, 'nbclassic': True, 'nbdime': True}}>}, 'ExtensionApp': {'log_level': 'DEBUG'}}
[D 2022-02-02 08:09:32.745 ServerApp] Config changed: {'ServerApp': {'config_file': '/home/jupyter/.jupyter/jupyter_notebook_config.py', 'log_level': 'DEBUG', 'jpserver_extensions': <LazyConfigValue value={'jupyterlab': True, 'beatrix_jupyterlab': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyterlab_git': True, 'jupytext': True, 'nbclassic': True, 'nbdime': True}>}, 'ExtensionApp': {'log_level': 'DEBUG'}, 'JupyterApp': {'kernel_spec_manager_class': 'nb_conda_kernels.CondaKernelSpecManager'}}
[I 2022-02-02 08:09:32.746 ServerApp] jupyter_server_mathjax | extension was successfully linked.
[I 2022-02-02 08:09:32.746 ServerApp] jupyter_server_proxy | extension was successfully linked.
[W 2022-02-02 08:09:32.749 LabApp] Config option `kernel_spec_manager_class` not recognized by `LabApp`.
[W 2022-02-02 08:09:32.753 LabApp] Config option `kernel_spec_manager_class` not recognized by `LabApp`.
[W 2022-02-02 08:09:32.760 LabApp] Config option `kernel_spec_manager_class` not recognized by `LabApp`.
[D 2022-02-02 08:09:32.761 LabApp] Config changed: {'JupyterApp': {'kernel_spec_manager_class': 'nb_conda_kernels.CondaKernelSpecManager'}, 'NotebookApp': {}, 'ServerApp': {'config_file': '/home/jupyter/.jupyter/jupyter_notebook_config.py', 'log_level': 'DEBUG', 'jpserver_extensions': <LazyConfigValue value={'jupyterlab': True, 'beatrix_jupyterlab': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyterlab_git': True, 'jupytext': True, 'nbclassic': True, 'nbdime': True}>}, 'ExtensionApp': {'log_level': 'DEBUG'}}
[I 2022-02-02 08:09:32.762 ServerApp] jupyterlab | extension was successfully linked.
[I 2022-02-02 08:09:32.762 ServerApp] jupyterlab_git | extension was successfully linked.
[I 2022-02-02 08:09:32.762 ServerApp] jupytext | extension was successfully linked.
[W 2022-02-02 08:09:32.765 NotebookApp] Config option `kernel_spec_manager_class` not recognized by `NotebookApp`.
[W 2022-02-02 08:09:32.768 NotebookApp] Config option `kernel_spec_manager_class` not recognized by `NotebookApp`.
[W 2022-02-02 08:09:32.774 NotebookApp] Config option `kernel_spec_manager_class` not recognized by `NotebookApp`.
[D 2022-02-02 08:09:32.774 NotebookApp] Config changed: {'JupyterApp': {'kernel_spec_manager_class': 'nb_conda_kernels.CondaKernelSpecManager'}, 'NotebookApp': {'nbserver_extensions': {'nb_conda': True, 'jupyter_http_over_ws': True}}, 'ServerApp': {'config_file': '/home/jupyter/.jupyter/jupyter_notebook_config.py', 'log_level': 'DEBUG', 'jpserver_extensions': <LazyConfigValue value={'jupyterlab': True, 'beatrix_jupyterlab': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyterlab_git': True, 'jupytext': True, 'nbclassic': True, 'nbdime': True}>}, 'ExtensionApp': {'log_level': 'DEBUG'}}
[I 2022-02-02 08:09:32.778 ServerApp] Writing Jupyter server cookie secret to /home/gogasca/.local/share/jupyter/runtime/jupyter_cookie_secret
[D 2022-02-02 08:09:32.782 ServerApp] Paths used for configuration of jupyter_notebook_config: 
        /home/gogasca/.jupyter/jupyter_notebook_config.json
[D 2022-02-02 08:09:32.782 ServerApp] Paths used for configuration of jupyter_notebook_config: 
        /etc/jupyter/jupyter_notebook_config.json
[D 2022-02-02 08:09:32.783 ServerApp] Paths used for configuration of jupyter_notebook_config: 
        /usr/local/etc/jupyter/jupyter_notebook_config.json
[D 2022-02-02 08:09:32.784 ServerApp] Paths used for configuration of jupyter_notebook_config: 
        /opt/conda/etc/jupyter/jupyter_notebook_config.d/jupyter-server-proxy-notebookserverextension.json
        /opt/conda/etc/jupyter/jupyter_notebook_config.d/jupyterlab.json
        /opt/conda/etc/jupyter/jupyter_notebook_config.d/jupyterlab_git.json
        /opt/conda/etc/jupyter/jupyter_notebook_config.d/jupytext.json
        /opt/conda/etc/jupyter/jupyter_notebook_config.d/nbdime.json
        /opt/conda/etc/jupyter/jupyter_notebook_config.json
[D 2022-02-02 08:09:32.784 ServerApp] Paths used for configuration of jupyter_notebook_config: 
        /home/gogasca/.local/etc/jupyter/jupyter_notebook_config.json
[D 2022-02-02 08:09:32.785 ServerApp] Paths used for configuration of jupyter_notebook_config: 
        /home/gogasca/.jupyter/jupyter_notebook_config.json
[I 2022-02-02 08:09:32.787 ServerApp] nb_conda | extension was found and enabled by nbclassic. Consider moving the extension to Jupyter Server's extension paths.
[I 2022-02-02 08:09:32.787 ServerApp] nb_conda | extension was successfully linked.
[I 2022-02-02 08:09:32.789 ServerApp] jupyter_http_over_ws | extension was found and enabled by nbclassic. Consider moving the extension to Jupyter Server's extension paths.
[I 2022-02-02 08:09:32.789 ServerApp] jupyter_http_over_ws | extension was successfully linked.
[I 2022-02-02 08:09:32.789 ServerApp] nbclassic | extension was successfully linked.
[I 2022-02-02 08:09:32.789 ServerApp] nbdime | extension was successfully linked.
[D 2022-02-02 08:09:32.790 ServerApp] Config changed: {'ExtensionApp': {'log_level': 'DEBUG'}, 'JupyterApp': {'kernel_spec_manager_class': 'nb_conda_kernels.CondaKernelSpecManager'}, 'NotebookApp': {'nbserver_extensions': {'nb_conda': True, 'jupyter_http_over_ws': True}}, 'ServerApp': {'config_file': '/home/jupyter/.jupyter/jupyter_notebook_config.py', 'log_level': 'DEBUG', 'jpserver_extensions': <LazyConfigValue value={'jupyterlab': True, 'beatrix_jupyterlab': True, 'jupyter_server_mathjax': True, 'jupyter_server_proxy': True, 'jupyterlab_git': True, 'jupytext': True, 'nbclassic': True, 'nbdime': True}>}}
[D 2022-02-02 08:09:32.791 ServerApp] Raising open file limit: soft 1024->4096; hard 1048576->1048576
[D 2022-02-02 08:09:32.792 ServerApp] [nb_conda_kernels] refreshing conda info
[I 2022-02-02 08:09:33.136 ServerApp] [nb_conda_kernels] enabled, 1 kernels found
[I 2022-02-02 08:09:33.161 ServerApp] nbclassic | extension was successfully loaded.
[I 2022-02-02 08:09:33.163 ServerApp] beatrix_jupyterlab | extension was successfully loaded.
jupyter_http_over_ws extension initialized. Listening on /http_over_websocket
[I 2022-02-02 08:09:33.164 ServerApp] jupyter_http_over_ws | extension was successfully loaded.
[I 2022-02-02 08:09:33.165 ServerApp] jupyter_server_mathjax | extension was successfully loaded.
[I 2022-02-02 08:09:33.177 ServerApp] jupyter_server_proxy | extension was successfully loaded.
[I 2022-02-02 08:09:33.178 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.7/site-packages/jupyterlab
[I 2022-02-02 08:09:33.178 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 2022-02-02 08:09:33.183 ServerApp] jupyterlab | extension was successfully loaded.
[I 2022-02-02 08:09:33.188 ServerApp] jupyterlab_git | extension was successfully loaded.
[I 2022-02-02 08:09:33.188 ServerApp] [Jupytext Server Extension] Deriving a JupytextContentsManager from LargeFileManager
[I 2022-02-02 08:09:33.190 ServerApp] jupytext | extension was successfully loaded.
[I 2022-02-02 08:09:33.191 ServerApp] [nb_conda] enabled
[I 2022-02-02 08:09:33.191 ServerApp] nb_conda | extension was successfully loaded.
[D 2022-02-02 08:09:33.253 ServerApp] Using default logger
[D 2022-02-02 08:09:33.254 ServerApp] Using default logger
[D 2022-02-02 08:09:33.254 ServerApp] Using default logger
[D 2022-02-02 08:09:33.254 ServerApp] Using default logger
[D 2022-02-02 08:09:33.254 ServerApp] Using default logger
[D 2022-02-02 08:09:33.254 ServerApp] Using default logger
[I 2022-02-02 08:09:33.257 ServerApp] nbdime | extension was successfully loaded.
[I 2022-02-02 08:09:33.258 ServerApp] Serving notebooks from local directory: /home/gogasca
[I 2022-02-02 08:09:33.258 ServerApp] Jupyter Server 1.13.1 is running at:
[I 2022-02-02 08:09:33.258 ServerApp] http://localhost:8888/lab?token=0be64d1115747cdd0726876d15ece5ba15c4032127b508f1
[I 2022-02-02 08:09:33.258 ServerApp]  or http://127.0.0.1:8888/lab?token=0be64d1115747cdd0726876d15ece5ba15c4032127b508f1
[I 2022-02-02 08:09:33.258 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 2022-02-02 08:09:33.263 ServerApp] No web browser found: could not locate runnable browser.
[C 2022-02-02 08:09:33.263 ServerApp] 
    
    To access the server, open this file in a browser:
        file:///home/gogasca/.local/share/jupyter/runtime/jpserver-4572-open.html
    Or copy and paste one of these URLs:
        http://localhost:8888/lab?token=0be64d1115747cdd0726876d15ece5ba15c4032127b508f1
     or http://127.0.0.1:8888/lab?token=0be64d1115747cdd0726876d15ece5ba15c4032127b508f1
1 Answers

You can enforce failure on configuration errors by configuring environment variable TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR to 1 or true (see docs); on Linux this can be done by prepending the startup command like so:

TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR=1 jupyter lab

If you would like it to become a new default, there is a feature request marked as good first issue here: https://github.com/jupyterlab/jupyterlab/issues/5716

Related