Skip to content

Prepare for jupyter_server preferred_dir fix #324

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

Merged
merged 8 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

# Minimal makefile for Sphinx documentation
#

Expand Down
3 changes: 3 additions & 0 deletions docs/make.bat
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
rem Copyright (c) Jupyter Development Team.
rem Distributed under the terms of the Modified BSD License.

@ECHO OFF

pushd %~dp0
Expand Down
3 changes: 3 additions & 0 deletions docs/source/api/app.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. Copyright (c) Jupyter Development Team.
.. Distributed under the terms of the Modified BSD License.

===========
Application
===========
Expand Down
3 changes: 3 additions & 0 deletions docs/source/api/config.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. Copyright (c) Jupyter Development Team.
.. Distributed under the terms of the Modified BSD License.

======
Config
======
Expand Down
3 changes: 3 additions & 0 deletions docs/source/api/handlers.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. Copyright (c) Jupyter Development Team.
.. Distributed under the terms of the Modified BSD License.

========
Handlers
========
Expand Down
3 changes: 3 additions & 0 deletions docs/source/api/index.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. Copyright (c) Jupyter Development Team.
.. Distributed under the terms of the Modified BSD License.

---------------------
JupyterLab Server API
---------------------
Expand Down
3 changes: 3 additions & 0 deletions docs/source/api/process.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. Copyright (c) Jupyter Development Team.
.. Distributed under the terms of the Modified BSD License.

=======
Process
=======
Expand Down
3 changes: 3 additions & 0 deletions docs/source/api/rest.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. Copyright (c) Jupyter Development Team.
.. Distributed under the terms of the Modified BSD License.

--------
REST API
--------
Expand Down
3 changes: 3 additions & 0 deletions docs/source/api/spec.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. Copyright (c) Jupyter Development Team.
.. Distributed under the terms of the Modified BSD License.

=============
OpenAPI Specs
=============
Expand Down
3 changes: 3 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
Expand Down
3 changes: 3 additions & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.. Copyright (c) Jupyter Development Team.
.. Distributed under the terms of the Modified BSD License.

.. jupyterlab_server documentation master file, created by
sphinx-quickstart on Tue Mar 30 03:25:58 2021.
You can adapt this file completely to your liking, but it should at least
Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/__main__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""CLI entry point for jupyterlab server."""
import sys

Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""
store the current version info of the server.

Expand Down
24 changes: 16 additions & 8 deletions jupyterlab_server/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import os
import pathlib
import warnings
from functools import lru_cache
from urllib.parse import urlparse
Expand Down Expand Up @@ -84,16 +85,23 @@ def get_page_config(self):
page_config["store_id"] = self.application.store_id # type:ignore

server_root = os.path.normpath(os.path.expanduser(server_root))
preferred_path = ""
try:
# Remove the server_root from pref dir
if self.serverapp.preferred_dir != server_root:
page_config["preferredPath"] = "/" + os.path.relpath(
self.serverapp.preferred_dir, server_root
)
else:
page_config["preferredPath"] = "/"
preferred_path = self.serverapp.contents_manager.preferred_dir
except Exception:
page_config["preferredPath"] = "/"
# FIXME: Remove fallback once CM.preferred_dir is ubiquitous.
try:
# Remove the server_root from app pref dir
if self.serverapp.preferred_dir and self.serverapp.preferred_dir != server_root:
preferred_path = (
pathlib.Path(self.serverapp.preferred_dir)
.relative_to(server_root)
.as_posix()
)
except Exception:
pass # we do not require the preferred_dir trait to be present
# JupyterLab relies on an unset/default path being "/"
page_config["preferredPath"] = preferred_path or "/"

self.application.store_id += 1 # type:ignore

Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/licenses_app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""A license reporting CLI

Mostly ready-to-use, the downstream must provide the location of the application's
Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/process_app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""A lab app that runs a sub process for a demo or a test."""
import sys

Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/pytest_plugin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""pytest fixtures."""
import json
import os
Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/server.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""Server api."""
from jupyter_server import _tz as tz # noqa
from jupyter_server.base.handlers import (
Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/spec.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""OpenAPI spec utils."""
import os
import typing
Expand Down
5 changes: 5 additions & 0 deletions jupyterlab_server/templates/403.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<!--
~ Copyright (c) Jupyter Development Team.
~ Distributed under the terms of the Modified BSD License.
-->

<!DOCTYPE html>
<html>
<head>
Expand Down
5 changes: 5 additions & 0 deletions jupyterlab_server/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<!--
~ Copyright (c) Jupyter Development Team.
~ Distributed under the terms of the Modified BSD License.
-->

<!DOCTYPE html>
<html lang="en">
<head>
Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""Testing utils."""
import json
import os
Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/translation_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""
Localization utilities to find available language packs and packages with
localization data.
Expand Down
3 changes: 3 additions & 0 deletions jupyterlab_server/workspaces_app.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""A workspace management CLI"""
import json
import sys
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

[build-system]
requires = ["hatchling>=1.5"]
build-backend = "hatchling.build"
Expand Down Expand Up @@ -69,7 +72,7 @@ openapi = [
test = [
"codecov",
"ipykernel",
"pytest-jupyter[server]>=0.6",
"pytest-jupyter[server]>=0.6.2",
"jupyterlab_server[openapi]",
"openapi-spec-validator>=0.5.1",
"sphinxcontrib_spelling",
Expand Down Expand Up @@ -143,6 +146,7 @@ filterwarnings = [
"module:make_current is deprecated:DeprecationWarning",
"module:clear_current is deprecated:DeprecationWarning",
"module:There is no current event loop:DeprecationWarning",
"ignore:ServerApp.preferred_dir config is deprecated:FutureWarning",
"ignore:Passing a schema to Validator.iter_errors:DeprecationWarning",
"module:Subclassing validator classes is not intended to be part of their public API:DeprecationWarning"
]
Expand Down
2 changes: 2 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

import os

os.environ["JUPYTER_PLATFORM_DIRS"] = "1"
Expand Down
3 changes: 3 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

import json
import os

Expand Down
106 changes: 106 additions & 0 deletions tests/test_labapp.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""Basic tests for the lab handlers.
"""

import json
import re
from pathlib import Path

import pytest
import tornado.httpclient

Expand All @@ -19,6 +26,17 @@ def notebooks(jp_create_notebook, labserverapp):
return nbpaths


def extract_page_config(html):
return json.loads(
re.search(
r'<script id="jupyter-config-data" type="application/json">\s*(?P<data>.*?)\s*</script>',
html,
).group( # type: ignore
'data'
)
)


async def test_lab_handler(notebooks, jp_fetch):
r = await jp_fetch("lab", "jlab_test_notebooks")
assert r.code == 200
Expand All @@ -28,6 +46,94 @@ async def test_lab_handler(notebooks, jp_fetch):
assert "JupyterLab Server Application" in html


async def test_page_config(labserverapp, jp_fetch):
r = await jp_fetch("lab")
assert r.code == 200
# Check that the lab template is loaded
html = r.body.decode()
page_config = extract_page_config(html)
assert page_config['treePath'] == ""
assert page_config['preferredPath'] == "/"

def ispath(p):
return p.endswith("Dir") or p.endswith("Path") or p == "serverRoot"

nondirs = {k: v for k, v in page_config.items() if not ispath(k)}
assert nondirs == {
'appName': 'JupyterLab Server Application',
'appNamespace': 'jupyterlab_server',
'appUrl': '/lab',
'appVersion': '',
'baseUrl': '/a%40b/',
'cacheFiles': True,
'disabledExtensions': [],
'federated_extensions': [],
'fullAppUrl': '/a%40b/lab',
'fullLabextensionsUrl': '/a%40b/lab/extensions',
'fullLicensesUrl': '/a%40b/lab/api/licenses',
'fullListingsUrl': '/a%40b/lab/api/listings',
'fullMathjaxUrl': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js',
'fullSettingsUrl': '/a%40b/lab/api/settings',
'fullStaticUrl': '/a%40b/static/jupyterlab_server',
'fullThemesUrl': '/a%40b/lab/api/themes',
'fullTranslationsApiUrl': '/a%40b/lab/api/translations',
'fullTreeUrl': '/a%40b/lab/tree',
'fullWorkspacesApiUrl': '/a%40b/lab/api/workspaces',
'ignorePlugins': [],
'labextensionsUrl': '/lab/extensions',
'licensesUrl': '/lab/api/licenses',
'listingsUrl': '/lab/api/listings',
'mathjaxConfig': 'TeX-AMS_HTML-full,Safe',
'mode': 'multiple-document',
'notebookStartsKernel': True,
'settingsUrl': '/lab/api/settings',
'store_id': 0,
'terminalsAvailable': True,
'themesUrl': '/lab/api/themes',
'translationsApiUrl': '/lab/api/translations',
'treeUrl': '/lab/tree',
'workspace': 'default',
'workspacesApiUrl': '/lab/api/workspaces',
'wsUrl': '',
}


@pytest.fixture(scope="function")
def serverapp_preferred_dir(jp_server_config, jp_root_dir):
preferred_dir = Path(jp_root_dir, "my", "preferred_dir")
preferred_dir.mkdir(parents=True, exist_ok=True)
jp_server_config.ServerApp.preferred_dir = str(preferred_dir)
return preferred_dir


async def test_app_preferred_dir(serverapp_preferred_dir, labserverapp, jp_fetch):
r = await jp_fetch("lab")
assert r.code == 200
# Check that the lab template is loaded
html = r.body.decode()
page_config = extract_page_config(html)
api_path = str(serverapp_preferred_dir.relative_to(labserverapp.serverapp.root_dir).as_posix())
assert page_config['preferredPath'] == api_path


async def test_contents_manager_preferred_dir(jp_root_dir, labserverapp, jp_fetch):
preferred_dir = Path(jp_root_dir, "my", "preferred_dir")
preferred_dir.mkdir(parents=True, exist_ok=True)
try:
_ = labserverapp.serverapp.contents_manager.preferred_dir
labserverapp.serverapp.contents_manager.preferred_dir = str(preferred_dir)
except AttributeError:
pytest.skip("Skipping contents manager test, trait not present")

r = await jp_fetch("lab")
assert r.code == 200
# Check that the lab template is loaded
html = r.body.decode()
page_config = extract_page_config(html)
api_path = str(preferred_dir.relative_to(labserverapp.serverapp.root_dir).as_posix())
assert page_config['preferredPath'] == api_path


async def test_notebook_handler(notebooks, jp_fetch):
for nbpath in notebooks:
r = await jp_fetch("lab", nbpath)
Expand Down
3 changes: 3 additions & 0 deletions tests/test_licenses_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

"""Test the Settings service API.
"""
import csv
Expand Down
3 changes: 3 additions & 0 deletions tests/test_listings_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

import json

import requests_mock
Expand Down
3 changes: 3 additions & 0 deletions tests/test_process.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

import os
import sys
import warnings
Expand Down
Loading