Hello,
I’m trying to run JupyterHub in API-only mode. I got to the part where I start the user’s instance through API, however, when I try to navigate to the URL printed out by the Hub console, this is what happens:
This is the URL I get redirected to:
http://127.0.0.1:50585/hub/api/oauth2/authorize?client_id=jupyterhub-user-milos%2540milos.com&redirect_uri=%2Fuser%2Fmilos%40milos.com%2Foauth_callback&response_type=code&state=eyJ1dWlkIjogIjYyYTI2NzA0MmU2NTQzNmY5NmU0NmY5MjQxNTYzZmQwIiwgIm5leHRfdXJsIjogIi91c2VyL21pbG9zQG1pbG9zLmNvbS9sYWI_dG9rZW49In0
The environment I’m running the code in:
jupyter==1.0.0
jupyter_nbextensions_configurator==0.6.3
jupyterhub==4.0.2
notebook==6.5.4
configurable-http-proxy==0.3.0
jupyterlab==4.0.9
…with this JupyterHub config:
c = get_config() # noqa
c.JupyterHub.allow_named_servers = True
c.JupyterHub.spawner_class = "simple"
c.JupyterHub.authenticator_class = "dummy"
c.JupyterHub.hub_routespec = "/hub/api" # <-- API only mode
c.JupyterHub.services = [
{
"name": "my-service",
"url": "http://localhost:8012/services/my-service",
"admin": True,
"api_token": "812a587d-8c23-4a60-873e-713c87084076",
},
]
c.Authenticator.delete_invalid_users = True
And this is the console output when the local process spawner does it’s thing:
[I 2023-12-12 17:18:27.795 JupyterHub provider:659] Creating oauth client jupyterhub-user-milos%40milos.com
[I 2023-12-12 17:18:27.830 JupyterHub spawner:1689] Spawning jupyterhub-singleuser
[W 2023-12-12 17:18:28.863 ServerApp] A `_jupyter_server_extension_points` function was not found in jupyter_lsp. Instead, a `_jupyter_server_extension_paths` function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
[W 2023-12-12 17:18:29.397 ServerApp] A `_jupyter_server_extension_points` function was not found in nbclassic. Instead, a `_jupyter_server_extension_paths` function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
[W 2023-12-12 17:18:29.397 ServerApp] A `_jupyter_server_extension_points` function was not found in notebook_shim. Instead, a `_jupyter_server_extension_paths` function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
[I 2023-12-12 17:18:29.398 ServerApp] jupyter_lsp | extension was successfully linked.
[I 2023-12-12 17:18:29.401 ServerApp] jupyter_server_terminals | extension was successfully linked.
[I 2023-12-12 17:18:29.402 JupyterHubSingleUser] Starting jupyterhub single-user server extension version 4.0.2
[I 2023-12-12 17:18:29.402 JupyterHubSingleUser] Using default url from server extension lab: /lab
[I 2023-12-12 17:18:29.405 ServerApp] jupyterhub | extension was successfully linked.
[W 2023-12-12 17:18:29.406 LabApp] 'extra_template_paths' was found in both NotebookApp and ServerApp. This is likely a recent change. This config will only be set in NotebookApp. Please check if you should also config these traits in ServerApp for your purpose.
[I 2023-12-12 17:18:29.409 ServerApp] jupyterlab | extension was successfully linked.
[W 2023-12-12 17:18:29.411 NotebookApp] 'extra_template_paths' was found in both NotebookApp and ServerApp. This is likely a recent change. This config will only be set in NotebookApp. Please check if you should also config these traits in ServerApp for your purpose.
[I 2023-12-12 17:18:29.413 ServerApp] nbclassic | extension was successfully linked.
[I 2023-12-12 17:18:29.948 ServerApp] Extension package jupyter_nbextensions_configurator took 0.2808s to import
[W 2023-12-12 17:18:29.948 ServerApp] A `_jupyter_server_extension_points` function was not found in jupyter_nbextensions_configurator. Instead, a `_jupyter_server_extension_paths` function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
[I 2023-12-12 17:18:29.948 ServerApp] jupyter_nbextensions_configurator | extension was found and enabled by notebook_shim. Consider moving the extension to Jupyter Server's extension paths.
[I 2023-12-12 17:18:29.948 ServerApp] jupyter_nbextensions_configurator | extension was successfully linked.
[I 2023-12-12 17:18:29.949 ServerApp] notebook_shim | extension was successfully linked.
[I 2023-12-12 17:18:29.976 ServerApp] notebook_shim | extension was successfully loaded.
[I 2023-12-12 17:18:29.978 ServerApp] jupyter_lsp | extension was successfully loaded.
[I 2023-12-12 17:18:29.978 ServerApp] [jupyter_nbextensions_configurator] enabled 0.6.3
[I 2023-12-12 17:18:29.978 ServerApp] jupyter_nbextensions_configurator | extension was successfully loaded.
[I 2023-12-12 17:18:29.979 ServerApp] jupyter_server_terminals | extension was successfully loaded.
[I 2023-12-12 17:18:29.984 JupyterHub log:191] 200 GET /hub/api (@127.0.0.1) 1.27ms
[I 2023-12-12 17:18:29.985 JupyterHubSingleUser] Updating Hub with activity every 300 seconds
[I 2023-12-12 17:18:29.985 ServerApp] jupyterhub | extension was successfully loaded.
[I 2023-12-12 17:18:29.989 LabApp] JupyterLab extension loaded from /home/milos/.pyenv/versions/3.11.4/envs/myhub/lib/python3.11/site-packages/jupyterlab
[I 2023-12-12 17:18:29.989 LabApp] JupyterLab application directory is /home/milos/.pyenv/versions/3.11.4/envs/myhub/share/jupyter/lab
[I 2023-12-12 17:18:29.989 LabApp] Extension Manager is 'pypi'.
[I 2023-12-12 17:18:29.992 ServerApp] jupyterlab | 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.
[I 2023-12-12 17:18:29.997 ServerApp] nbclassic | extension was successfully loaded.
[I 2023-12-12 17:18:29.998 ServerApp] Serving notebooks from local directory: /tmp/milos@milos.com
[I 2023-12-12 17:18:29.998 ServerApp] Jupyter Server 2.12.1 is running at:
[I 2023-12-12 17:18:29.998 ServerApp] http://127.0.0.1:38941/user/milos@milos.com/lab?token=...
[I 2023-12-12 17:18:29.998 ServerApp] http://127.0.0.1:38941/user/milos@milos.com/lab?token=...
[I 2023-12-12 17:18:29.998 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[I 2023-12-12 17:18:30.022 JupyterHub log:191] 200 POST /hub/api/users/milos@milos.com/activity (milos@milos.com@127.0.0.1) 19.51ms
[I 2023-12-12 17:18:30.385 ServerApp] Skipped non-installed server(s): bash-language-server, dockerfile-language-server-nodejs, javascript-typescript-langserver, jedi-language-server, julia-language-server, pyright, python-language-server, python-lsp-server, r-languageserver, sql-language-server, texlab, typescript-language-server, unified-language-server, vscode-css-languageserver-bin, vscode-html-languageserver-bin, vscode-json-languageserver-bin, yaml-language-server
[I 2023-12-12 17:18:31.559 ServerApp] 302 GET /user/milos@milos.com/ -> /user/milos@milos.com/lab? (@127.0.0.1) 0.50ms
[W 2023-12-12 17:18:31.559 JupyterHub _version:37] Single-user server has no version header, which means it is likely < 0.8. Expected 4.0.2
[I 2023-12-12 17:18:31.560 JupyterHub base:990] User milos@milos.com took 3.799 seconds to start
[I 2023-12-12 17:18:31.560 JupyterHub proxy:330] Adding user milos@milos.com to proxy /user/milos@milos.com/ => http://127.0.0.1:38941
[I 2023-12-12 17:18:31,563 configurable_http_proxy] Adding route /user/milos@milos.com -> http://127.0.0.1:38941
[I 2023-12-12 17:18:31,563 configurable_http_proxy] Route added /user/milos@milos.com -> http://127.0.0.1:38941
[I 2023-12-12 17:18:31,563 configurable_http_proxy] 201 POST /api/routes/user/milos@milos.com
[I 2023-12-12 17:18:31.565 JupyterHub log:191] 201 POST /hub/api/users/milos%40milos.com/server (my-api@::1) 3819.75ms
I was hoping that someone could maybe tell me what am I doing wrong. Haven’t had much luck with docs and examples.
Also, regarding this part: JupyterHub and OAuth — JupyterHub documentation
Does this mean that the Hub API must remain a public API because of oauth2 in, e.g., k8s setup?