diff --git a/notebook/app.py b/notebook/app.py index d7cc0079a..9a969b50a 100644 --- a/notebook/app.py +++ b/notebook/app.py @@ -203,8 +203,16 @@ class NotebookHandler(NotebookBaseHandler): """A notebook page handler.""" @web.authenticated - def get(self, path: str | None = None) -> t.Any: # noqa: ARG002 - """Get the notebook page.""" + async def get(self, path: str = "") -> t.Any: + """Get the notebook page. Redirect if it's a directory.""" + path = path.strip("/") + cm = self.contents_manager + + if await ensure_async(cm.dir_exists(path=path)): + url = ujoin(self.base_url, "tree", url_escape(path)) + self.log.debug("Redirecting %s to %s since path is a directory", self.request.path, url) + self.redirect(url) + return None tpl = self.render_template("notebooks.html", page_config=self.get_page_config()) return self.write(tpl) diff --git a/tests/test_app.py b/tests/test_app.py index 86a3b994c..93a9a77e6 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -3,7 +3,7 @@ import os import pytest from tornado.httpclient import HTTPClientError -from notebook.app import JupyterNotebookApp, TreeHandler +from notebook.app import JupyterNotebookApp, NotebookHandler, TreeHandler @pytest.fixture() @@ -32,6 +32,16 @@ async def test_notebook_handler(notebooks, jp_fetch): html = r.body.decode() assert "Jupyter Notebook" in html + redirected_url = None + + def redirect(self, url): + nonlocal redirected_url + redirected_url = url + + NotebookHandler.redirect = redirect + await jp_fetch("notebooks", "jlab_test_notebooks") + assert redirected_url == "/a%40b/tree/jlab_test_notebooks" + async def test_tree_handler(notebooks, notebookapp, jp_fetch): app: JupyterNotebookApp = notebookapp