Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

/metrics endpoint requires auth even if token and password are empty #5973

Closed
blairdrummond opened this issue Feb 3, 2021 · 6 comments · Fixed by #5974
Closed

/metrics endpoint requires auth even if token and password are empty #5973

blairdrummond opened this issue Feb 3, 2021 · 6 comments · Fixed by #5974

Comments

@blairdrummond
Copy link
Contributor

Describe the bug

When using the standard --NotebookApp.token="" --NotebookApp.password="" to disable auth, the fact that auth is turned off is not reflected in authenticate_prometheus. As a result the /metrics endpoint stops working (by default) after this commit

c0ab18a

On systems like Kubeflow and JupyterHub, this is unfortunate (and a breaking change), though it is solved by adding

--NotebookApp.authenticate_prometheus=False.

Perhaps authenticate_prometheus=False should be default if other authentication is also disabled?

To Reproduce

# Two commits to compare the behavior
POST_COMMIT=5cb007f03275
PRE_COMMIT=feacdbfc2e89

COMMIT=$PRE_COMMIT
docker run -p 8888:8888 \
    -e JUPYTER_ENABLE_LAB=yes \
    jupyter/minimal-notebook:$COMMIT \
    jupyter notebook --no-browser --ip=0.0.0.0 --ServerApp.allow_origin='*' \
    --NotebookApp.token='' --ServerApp.password=''

# works
curl http://0.0.0.0:8888/metrics

COMMIT=$POST_COMMIT
docker run -p 8888:8888 \
    -e JUPYTER_ENABLE_LAB=yes \
    jupyter/minimal-notebook:$COMMIT \
    jupyter notebook --no-browser --ip=0.0.0.0 --ServerApp.allow_origin='*' \
    --NotebookApp.token='' --ServerApp.password=''
    
# Does not work!!!
curl -s -o /dev/null -w "%{http_code}"  http://0.0.0.0:8888/metrics
# > 403%                                            

Both commands work if the flag --NotebookApp.authenticate_prometheus=False is added.

Expected behavior

If auth is disabled (empty token and password), then set authenticate_prometheus=False

@kevin-bates
Copy link
Member

Hi @blairdrummond - first of all, thanks for the great issue write-up - it's much appreciated!

I could go either way on this.

  • On one hand, which I suspect was @yuvipanda's intent, allowing unauthenticated access to metrics should always be explicit.
  • On the other hand, explicit termination of authentication should imply metrics be unauthenticated as well.

It's certainly safer to just toss this knob into the same bucket as the other authentication knobs and require that it too be explicitly disabled and never implied. But, what worked before Yuvi's commit now doesn't work, so I suppose there's a regression argument that can be made as well.

I guess I find myself leaning toward the regression argument side of things and that if the user has intentionally opened up their server, and ignored the corresponding warnings, then why not open up metrics as well. However, I'm also unaware of what information we include in these metrics and where that information ends up.

Others?

@yuvipanda
Copy link
Contributor

Here's a sample set of metrics from /metrics:

# HELP python_gc_objects_collected_total Objects collected during gc # TYPE python_gc_objects_collected_total counter python_gc_objects_collected_total{generation="0"} 15908.0 python_gc_objects_collected_total{generation="1"} 5366.0 python_gc_objects_collected_total{generation="2"} 6.0 # HELP python_gc_objects_uncollectable_total Uncollectable object found during GC # TYPE python_gc_objects_uncollectable_total counter python_gc_objects_uncollectable_total{generation="0"} 0.0 python_gc_objects_uncollectable_total{generation="1"} 0.0 python_gc_objects_uncollectable_total{generation="2"} 0.0 # HELP python_gc_collections_total Number of times this generation was collected # TYPE python_gc_collections_total counter python_gc_collections_total{generation="0"} 218.0 python_gc_collections_total{generation="1"} 19.0 python_gc_collections_total{generation="2"} 1.0 # HELP python_info Python platform information # TYPE python_info gauge python_info{implementation="CPython",major="3",minor="9",patchlevel="1",version="3.9.1"} 1.0 # HELP http_request_duration_seconds duration in seconds for all HTTP requests # TYPE http_request_duration_seconds histogram http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.005",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.01",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.025",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.05",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.075",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.1",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.25",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.5",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="0.75",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="1.0",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="2.5",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="5.0",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="7.5",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="10.0",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.tree.handlers.TreeHandler",le="+Inf",method="GET",status_code="200"} 2.0 http_request_duration_seconds_count{handler="notebook.tree.handlers.TreeHandler",method="GET",status_code="200"} 2.0 http_request_duration_seconds_sum{handler="notebook.tree.handlers.TreeHandler",method="GET",status_code="200"} 0.0897989273071289 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.005",method="GET",status_code="200"} 3.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.01",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.025",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.05",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.075",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.1",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.25",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.75",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="1.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="2.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="5.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="7.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="10.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="+Inf",method="GET",status_code="200"} 4.0 http_request_duration_seconds_count{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="200"} 4.0 http_request_duration_seconds_sum{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="200"} 0.014249801635742188 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.005",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.01",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.025",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.05",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.075",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.1",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.25",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.5",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.75",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="1.0",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="2.5",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="5.0",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="7.5",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="10.0",method="GET",status_code="304"} 16.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="+Inf",method="GET",status_code="304"} 16.0 http_request_duration_seconds_count{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="304"} 16.0 http_request_duration_seconds_sum{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="304"} 0.02852606773376465 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.005",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.01",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.025",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.05",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.075",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.1",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.25",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.5",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="0.75",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="1.0",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="2.5",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="5.0",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="7.5",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="10.0",method="GET",status_code="200"} 6.0 http_request_duration_seconds_bucket{handler="notebook.services.config.handlers.ConfigHandler",le="+Inf",method="GET",status_code="200"} 6.0 http_request_duration_seconds_count{handler="notebook.services.config.handlers.ConfigHandler",method="GET",status_code="200"} 6.0 http_request_duration_seconds_sum{handler="notebook.services.config.handlers.ConfigHandler",method="GET",status_code="200"} 0.0272061824798584 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.005",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.01",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.025",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.05",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.075",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.1",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.25",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="0.75",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="1.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="2.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="5.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="7.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="10.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.terminal.api_handlers.TerminalRootHandler",le="+Inf",method="GET",status_code="200"} 4.0 http_request_duration_seconds_count{handler="notebook.terminal.api_handlers.TerminalRootHandler",method="GET",status_code="200"} 4.0 http_request_duration_seconds_sum{handler="notebook.terminal.api_handlers.TerminalRootHandler",method="GET",status_code="200"} 0.010448932647705078 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.005",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.01",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.025",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.05",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.075",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.1",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.25",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.5",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.75",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="1.0",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="2.5",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="5.0",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="7.5",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="10.0",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="+Inf",method="GET",status_code="200"} 2.0 http_request_duration_seconds_count{handler="notebook.services.sessions.handlers.SessionRootHandler",method="GET",status_code="200"} 2.0 http_request_duration_seconds_sum{handler="notebook.services.sessions.handlers.SessionRootHandler",method="GET",status_code="200"} 0.006663322448730469 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.005",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.01",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.025",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.05",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.075",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.1",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.25",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.75",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="1.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="2.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="5.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="7.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="10.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="+Inf",method="GET",status_code="200"} 1.0 http_request_duration_seconds_count{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",method="GET",status_code="200"} 1.0 http_request_duration_seconds_sum{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",method="GET",status_code="200"} 0.013926982879638672 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.005",method="GET",status_code="200"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.01",method="GET",status_code="200"} 3.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.025",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.05",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.075",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.1",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.25",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="0.75",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="1.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="2.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="5.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="7.5",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="10.0",method="GET",status_code="200"} 4.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.ContentsHandler",le="+Inf",method="GET",status_code="200"} 4.0 http_request_duration_seconds_count{handler="notebook.services.contents.handlers.ContentsHandler",method="GET",status_code="200"} 4.0 http_request_duration_seconds_sum{handler="notebook.services.contents.handlers.ContentsHandler",method="GET",status_code="200"} 0.027486324310302734 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.005",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.01",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.025",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.05",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.075",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.1",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.25",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="0.75",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="1.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="2.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="5.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="7.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="10.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.PrometheusMetricsHandler",le="+Inf",method="GET",status_code="200"} 1.0 http_request_duration_seconds_count{handler="notebook.base.handlers.PrometheusMetricsHandler",method="GET",status_code="200"} 1.0 http_request_duration_seconds_sum{handler="notebook.base.handlers.PrometheusMetricsHandler",method="GET",status_code="200"} 0.003545999526977539 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.005",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.01",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.025",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.05",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.075",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.1",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.25",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.5",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="0.75",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="1.0",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="2.5",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="5.0",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="7.5",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="10.0",method="GET",status_code="304"} 2.0 http_request_duration_seconds_bucket{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",le="+Inf",method="GET",status_code="304"} 2.0 http_request_duration_seconds_count{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",method="GET",status_code="304"} 2.0 http_request_duration_seconds_sum{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",method="GET",status_code="304"} 0.0045621395111083984 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.005",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.01",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.025",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.05",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.075",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.1",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.25",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.5",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="0.75",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="1.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="2.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="5.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="7.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="10.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.notebook.handlers.NotebookHandler",le="+Inf",method="GET",status_code="200"} 1.0 http_request_duration_seconds_count{handler="notebook.notebook.handlers.NotebookHandler",method="GET",status_code="200"} 1.0 http_request_duration_seconds_sum{handler="notebook.notebook.handlers.NotebookHandler",method="GET",status_code="200"} 0.6274099349975586 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.005",method="GET",status_code="404"} 0.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.01",method="GET",status_code="404"} 0.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.025",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.05",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.075",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.1",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.25",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.5",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="0.75",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="1.0",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="2.5",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="5.0",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="7.5",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="10.0",method="GET",status_code="404"} 1.0 http_request_duration_seconds_bucket{handler="notebook.base.handlers.FileFindHandler",le="+Inf",method="GET",status_code="404"} 1.0 http_request_duration_seconds_count{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="404"} 1.0 http_request_duration_seconds_sum{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="404"} 0.010910987854003906 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.005",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.01",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.025",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.05",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.075",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.1",method="GET",status_code="200"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.25",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="0.75",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="1.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="2.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="5.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="7.5",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="10.0",method="GET",status_code="200"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.contents.handlers.CheckpointsHandler",le="+Inf",method="GET",status_code="200"} 1.0 http_request_duration_seconds_count{handler="notebook.services.contents.handlers.CheckpointsHandler",method="GET",status_code="200"} 1.0 http_request_duration_seconds_sum{handler="notebook.services.contents.handlers.CheckpointsHandler",method="GET",status_code="200"} 0.13966989517211914 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.005",method="POST",status_code="201"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.01",method="POST",status_code="201"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.025",method="POST",status_code="201"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.05",method="POST",status_code="201"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.075",method="POST",status_code="201"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.1",method="POST",status_code="201"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.25",method="POST",status_code="201"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.5",method="POST",status_code="201"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="0.75",method="POST",status_code="201"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="1.0",method="POST",status_code="201"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="2.5",method="POST",status_code="201"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="5.0",method="POST",status_code="201"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="7.5",method="POST",status_code="201"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="10.0",method="POST",status_code="201"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.sessions.handlers.SessionRootHandler",le="+Inf",method="POST",status_code="201"} 1.0 http_request_duration_seconds_count{handler="notebook.services.sessions.handlers.SessionRootHandler",method="POST",status_code="201"} 1.0 http_request_duration_seconds_sum{handler="notebook.services.sessions.handlers.SessionRootHandler",method="POST",status_code="201"} 0.14969301223754883 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.005",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.01",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.025",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.05",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.075",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.1",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.25",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.5",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="0.75",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="1.0",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="2.5",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="5.0",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="7.5",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="10.0",method="GET",status_code="304"} 1.0 http_request_duration_seconds_bucket{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",le="+Inf",method="GET",status_code="304"} 1.0 http_request_duration_seconds_count{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",method="GET",status_code="304"} 1.0 http_request_duration_seconds_sum{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",method="GET",status_code="304"} 0.002521991729736328 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.005",method="GET",status_code="101"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.01",method="GET",status_code="101"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.025",method="GET",status_code="101"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.05",method="GET",status_code="101"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.075",method="GET",status_code="101"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.1",method="GET",status_code="101"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.25",method="GET",status_code="101"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.5",method="GET",status_code="101"} 0.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="0.75",method="GET",status_code="101"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="1.0",method="GET",status_code="101"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="2.5",method="GET",status_code="101"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="5.0",method="GET",status_code="101"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="7.5",method="GET",status_code="101"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="10.0",method="GET",status_code="101"} 1.0 http_request_duration_seconds_bucket{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",le="+Inf",method="GET",status_code="101"} 1.0 http_request_duration_seconds_count{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",method="GET",status_code="101"} 1.0 http_request_duration_seconds_sum{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",method="GET",status_code="101"} 0.7023880481719971 # HELP http_request_duration_seconds_created duration in seconds for all HTTP requests # TYPE http_request_duration_seconds_created gauge http_request_duration_seconds_created{handler="notebook.tree.handlers.TreeHandler",method="GET",status_code="200"} 1.612421559983511e+09 http_request_duration_seconds_created{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="200"} 1.6124215601527512e+09 http_request_duration_seconds_created{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="304"} 1.612421560172956e+09 http_request_duration_seconds_created{handler="notebook.services.config.handlers.ConfigHandler",method="GET",status_code="200"} 1.612421560421799e+09 http_request_duration_seconds_created{handler="notebook.terminal.api_handlers.TerminalRootHandler",method="GET",status_code="200"} 1.6124215604381561e+09 http_request_duration_seconds_created{handler="notebook.services.sessions.handlers.SessionRootHandler",method="GET",status_code="200"} 1.612421560443229e+09 http_request_duration_seconds_created{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",method="GET",status_code="200"} 1.612421560460205e+09 http_request_duration_seconds_created{handler="notebook.services.contents.handlers.ContentsHandler",method="GET",status_code="200"} 1.612421560505492e+09 http_request_duration_seconds_created{handler="notebook.base.handlers.PrometheusMetricsHandler",method="GET",status_code="200"} 1.6124215626871512e+09 http_request_duration_seconds_created{handler="notebook.services.kernelspecs.handlers.MainKernelSpecHandler",method="GET",status_code="304"} 1.612421569948545e+09 http_request_duration_seconds_created{handler="notebook.notebook.handlers.NotebookHandler",method="GET",status_code="200"} 1.612421572621929e+09 http_request_duration_seconds_created{handler="notebook.base.handlers.FileFindHandler",method="GET",status_code="404"} 1.612421573219779e+09 http_request_duration_seconds_created{handler="notebook.services.contents.handlers.CheckpointsHandler",method="GET",status_code="200"} 1.61242157344662e+09 http_request_duration_seconds_created{handler="notebook.services.sessions.handlers.SessionRootHandler",method="POST",status_code="201"} 1.612421573448736e+09 http_request_duration_seconds_created{handler="notebook.kernelspecs.handlers.KernelSpecResourceHandler",method="GET",status_code="304"} 1.612421573450347e+09 http_request_duration_seconds_created{handler="notebook.services.kernels.handlers.ZMQChannelsHandler",method="GET",status_code="101"} 1.612421574179942e+09 # HELP terminal_currently_running_total counter for how many terminals are running # TYPE terminal_currently_running_total gauge terminal_currently_running_total 0.0 # HELP kernel_currently_running_total counter for how many kernels are running labeled by type # TYPE kernel_currently_running_total gauge kernel_currently_running_total{type="python3"} 1.0

At the very least, I can gauge the following information from this just by looking at it:

  1. Number of running kernels, and what languages these kernels are in
  2. Number of currently active terminals
  3. Any file saves that have happened, and how many of them
  4. Interface used - JupyterLab vs Notebook vs...

Over a period of time, you can fetch this to get a lot of things - current user browser activity levels, kernels used, possible navigation through the UI, etc. IMO, this is all what I'd call sensitive user information, and can be fairly dangerous when combined with other sidechannel information.

In JupyterHub, authentication isn't disabled - just provided via different means than standard token / password.

That said, when authentication is explicitly disabled, I think it's fine for /metrics to be available without any auth, since it doesn't actually provide any information that you can't already get :)

@yuvipanda
Copy link
Contributor

Also, the authenticate_prometheus flag was introduced to allow disabling the auth check for /metrics without disabling all authentication. This lets you actually collect metrics from notebooks running on JupyterHub, since it was impractical to give a Prometheus server per-user access to the notebook server.

@kevin-bates
Copy link
Member

Thanks @yuvipanda - that was helpful.

@blairdrummond - did you want to take a crack at this? A similar PR would likely be desired in jupyter_server as well.

@blairdrummond
Copy link
Contributor Author

Sure thing, I'll take a crack!

@blairdrummond
Copy link
Contributor Author

@kevin-bates PR opened! I hope I did my due diligence!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants