How to access single user notebook in a web browser in API only mode?

I would like to inquire about how to run user notebooks in a web browser while in API only mode.

I’m interested in using JupyterHub’s API only mode to enable users to run their individual single-user JupyterLab servers.

I’ve configured the environment on AWS EKS by referring to “Zero to JupyterHub with Kubernetes.”

  • helm chart version 3.0.3

I followed the steps below:

  1. After configuring config.yaml as shown below, I logged in as the root user and generated an API Token.

    hub:
      config:
        Authenticator:
          admin_users:
            - root
    
  2. To use API Only mode, I changed the Authenticator to NullAuthenticator.
    I modified config.yaml as follows and performed a helm upgrade.

    hub:
      config:
        JupyterHub:
          authenticator_class: "null"
    
  3. I have successfully achieved the following workflow to obtain a user’s server URL through API calls:

    1. User creation
      • POST HUB_URL/hub/api/user/{user_name}
    2. User API token creation
      • POST HUB_URL/hub/api/user/{user_name}/tokens
    3. User server creation
      • POST HUB_URL/hub/api/user/{user_name}/server
    4. Obtaining the user server address and checking its status
      • GET HUB_URL/hub/api/user/{user_name}
  4. After confirming that servers.ready has become true in step 3.4, I attempted to run JupyterLab in the browser using the following user server URL:

    • HUB_URL/user/{user_name}/?token={user_api_token}

JupyterLab runs as expected, but icons are broken, and when I inspect the developer tools, I see websocket connection failures.

Could you please assist me in identifying where I might be going wrong? Your help would be greatly appreciated.

I suspect you are hitting this error, where cookie auth is not persisted from a token-in-url-authenticated request when using the new jupyterhub server extension. The workaround while waiting for a release is to use the older subclass implementation of jupyterhub-singleuser by setting JUPYTERHUB_SINGLEUSER_EXTENSION=0.

1 Like

JUPYTERHUB_SINGLEUSER_EXTENSION=0 fixed the problem for me, when I connect to the single user directly, however when I use an iframe, the problems persists. Anyone have any incite?

For i frame i recommend use SSL connection for jupyterhub that fixes the problem.

I’ve double-checked, but I still encounter this issue.

Looking at the output logs, it seems that the problem persists because authentication information is not being stored in the cookie when /…/kernelspecs/python3/logo-svg.svg is redirected to /hub/api/oauth2/authorize.

[I 2024-02-02 16:33:45.942 ServerApp] 302 GET /user/kghoon/ -> /user/kghoon/lab? (@10.112.0.62) 0.70ms
[I 2024-02-02 16:34:13.765 ServerApp] 200 GET /user/kghoon/lab?token=[secret] (kghoon@::ffff:127.0.0.1) 21.98ms
0.00s - Debugger warning: It seems that frozen modules are being used, which may
0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
0.00s - to python to disable frozen modules.
0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.
[I 2024-02-02 16:34:14.652 ServerApp] 200 GET /user/kghoon/api/kernelspecs?1706859254428 (kghoon@::ffff:127.0.0.1) 170.56ms
[I 2024-02-02 16:34:14.656 ServerApp] 200 GET /user/kghoon/api/me?1706859254428 (kghoon@::ffff:127.0.0.1) 1.83ms
[I 2024-02-02 16:34:14.660 ServerApp] 101 GET /user/kghoon/api/events/subscribe?token=[secret] (kghoon@::ffff:127.0.0.1) 5.61ms
[I 2024-02-02 16:34:14.744 ServerApp] 200 GET /user/kghoon/lab/api/settings?1706859254431 (kghoon@::ffff:127.0.0.1) 87.64ms
[I 2024-02-02 16:34:14.747 ServerApp] 200 GET /user/kghoon/api/sessions?1706859254436 (kghoon@::ffff:127.0.0.1) 87.84ms
[I 2024-02-02 16:34:14.748 ServerApp] 200 GET /user/kghoon/api/kernels?1706859254436 (kghoon@::ffff:127.0.0.1) 88.96ms
[I 2024-02-02 16:34:14.751 ServerApp] 200 GET /user/kghoon/api/kernelspecs?1706859254662 (kghoon@::ffff:127.0.0.1) 2.02ms
[I 2024-02-02 16:34:14.753 ServerApp] 200 GET /user/kghoon/api/terminals?1706859254436 (kghoon@::ffff:127.0.0.1) 1.37ms
[I 2024-02-02 16:34:14.755 ServerApp] 200 GET /user/kghoon/api/me?1706859254663 (kghoon@::ffff:127.0.0.1) 1.20ms
[I 2024-02-02 16:34:15.844 ServerApp] 200 GET /user/kghoon/lab/api/translations/default?1706859255773 (kghoon@::ffff:127.0.0.1) 15.92ms
[I 2024-02-02 16:34:15.881 ServerApp] 200 GET /user/kghoon/api/config/jupyterlabapputilsextensionannouncements?1706859255823 (kghoon@::ffff:127.0.0.1) 3.66ms
[W 2024-02-02 16:34:15.907 LabApp] Could not determine jupyterlab build status without nodejs
[I 2024-02-02 16:34:15.908 ServerApp] 200 GET /user/kghoon/lab/api/build?1706859255852 (kghoon@::ffff:127.0.0.1) 2.86ms
[I 2024-02-02 16:34:15.949 ServerApp] 200 GET /user/kghoon/lsp/status?1706859255893 (kghoon@::ffff:127.0.0.1) 3.27ms
[I 2024-02-02 16:34:16.015 ServerApp] 200 GET /user/kghoon/lab/api/settings/@jupyterlab/codemirror-extension:plugin?1706859255936 (kghoon@::ffff:127.0.0.1) 19.01ms
[I 2024-02-02 16:34:16.019 ServerApp] 200 GET /user/kghoon/lab/api/translations?1706859255905 (kghoon@::ffff:127.0.0.1) 60.82ms
[I 2024-02-02 16:34:16.023 ServerApp] 200 GET /user/kghoon/lab/api/settings/@jupyterlab/notebook-extension:panel?1706859255939 (kghoon@::ffff:127.0.0.1) 7.77ms
[I 2024-02-02 16:34:16.029 ServerApp] 200 GET /user/kghoon/api/contents?content=1&1706859255909 (kghoon@::ffff:127.0.0.1) 67.12ms
[I 2024-02-02 16:34:16.059 ServerApp] 200 GET /user/kghoon/lab/api/workspaces/default?1706859256003 (kghoon@::ffff:127.0.0.1) 2.55ms
[I 2024-02-02 16:34:16.093 ServerApp] 200 GET /user/kghoon/api/contents?content=1&1706859256030 (kghoon@::ffff:127.0.0.1) 9.85ms
[I 2024-02-02 16:34:16.104 ServerApp] 200 GET /user/kghoon/lab/api/settings?ids_only=true&1706859256045 (kghoon@::ffff:127.0.0.1) 6.90ms
[I 2024-02-02 16:34:16.145 ServerApp] 200 GET /user/kghoon/lab/api/news?1706859256046 (kghoon@::ffff:127.0.0.1) 39.98ms
[I 2024-02-02 16:34:16.207 ServerApp] 200 GET /user/kghoon/lab/api/update?1706859256105 (kghoon@::ffff:127.0.0.1) 49.68ms
[I 2024-02-02 16:34:16.669 ServerApp] 204 PUT /user/kghoon/lab/api/workspaces/default?1706859256574 (kghoon@::ffff:127.0.0.1) 1.66ms
[I 2024-02-02 16:34:16.706 ServerApp] 200 GET /user/kghoon/api/contents?content=1&1706859256641 (kghoon@::ffff:127.0.0.1) 9.86ms
[I 2024-02-02 16:34:16.807 ServerApp] 302 GET /user/kghoon/kernelspecs/python3/logo-svg.svg -> /hub/api/oauth2/authorize?client_id=jupyterhub-user-kghoon&redirect_uri=%2Fuser%2Fkghoon%2Foauth_callback&response_type=code&state=[secret] (@::ffff:127.0.0.1) 1.89ms
[I 2024-02-02 16:34:17.332 ServerApp] 204 PUT /user/kghoon/lab/api/workspaces/default?1706859257211 (kghoon@::ffff:127.0.0.1) 2.28ms
[I 2024-02-02 16:34:19.032 ServerApp] 200 GET /user/kghoon/lab/api/extensions?query&page=1&per_page=30&refresh=0&1706859257058 (kghoon@::ffff:127.0.0.1) 1917.13ms

config.yaml

hub:
  extraConfig:
      disable_singleuser_extension: |
        c.Spawner.environment.update(
          {
            "JUPYTERHUB_SINGLEUSER_EXTENSION": "0",
          }
        )
  • Helm chart version - 3.2.2-0.dev.git.6509.h23fd6095