Code Monkey home page Code Monkey logo

jupyterlab_server's Introduction

jupyterlab server

Build Status Documentation Status

Motivation

JupyterLab Server sits between JupyterLab and Jupyter Server, and provides a set of REST API handlers and utilities that are used by JupyterLab. It is a separate project in order to accommodate creating JupyterLab-like applications from a more limited scope.

Install

pip install jupyterlab_server

To include optional openapi dependencies, use:

pip install jupyterlab_server[openapi]

To include optional pytest_plugin dependencies, use:

pip install jupyterlab_server[test]

Usage

See the full documentation for API docs and REST endpoint descriptions.

Extending the Application

Subclass the LabServerApp and provide additional traits and handlers as appropriate for your application.

Contribution

Please see CONTRIBUTING.md for details.

jupyterlab_server's People

Contributors

afshin avatar ajbozarth avatar blink1073 avatar bollwyvl avatar brichet avatar dependabot[bot] avatar divyansshhh avatar echarles avatar fcollonval avatar github-actions[bot] avatar goanpeca avatar ian-r-rose avatar itsmevichu avatar jasongrout avatar jasonweill avatar jtpio avatar krassowski avatar mlucool avatar pre-commit-ci[bot] avatar santiagobasulto avatar saulshanabrook avatar seibs avatar sylvaincorlay avatar takavfx avatar telamonian avatar tgrout avatar toddrme2178 avatar vidartf avatar zelphirkaltstahl avatar zsailer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jupyterlab_server's Issues

test_data in the main package

I'd like to ask what is the point of having the test_data folder as a part of the main package. If I, as a user, install jupyterlab-server, I get this folder but it does not seem to be used anywhere outside tests that are not part of the main package.

Break up and make add_handlers overrideable

Elevator Pitch

Break up handlers.add_handlers into something more easily overrideable.

Motivation

Presently, add_handlers is a single monolithic function that does... something to the app that goes in. Some features can be disabled by (un-)configuring the URL, but this wouldn't prevent things from getting added to a future release of the application, e.g. EmailHandler, etc. that a downstream may not want.

The sterling work over on voila-dashboards/voila#846 raises the point of only getting the handlers you want, irrespective of the jupyterlab_server version you'd pull in. In the case of voila, things like workspaces and extension manager points may not be useful, while certain parts of translations, themes, licenses (#161) would be important, but not the writeable ones.

Design ideas

Build up something like LabCapabilities which handles actually installing different handlers. It probably would still expose add_handlers, but would be more configurable (but perhaps not traitlets.config-urable).

class LabCapabilities(HasTraits):
    allowed_capabilities = ...
    blocked_capabilities = ... 
    def add_handlers(self, handlers, extension_app): ...

At an even lower level, these might allow for blocking individual methods, e.g. disabling POST, etc.

{WorkspacesHandler: ["post"]}

Alternatives

Perhaps this could land in jupyter_server, e.g. as an OpenAPI contract which the ultimate application implementation could levy against all the stuff that might get installed via e.g. extension.

Attempted config merge of list and dict clobbers dict

Description

In the lab handler, we attempt to merge the page_config_data set on the webapp with the readout from the settings dir:

recursive_update(page_config, get_page_config(labextensions_path, settings_dir, logger=self.log))

The code that reads out data from the config file includes a part that converts dicts to lists:

# Convert dictionaries to lists to give to the front end
for (key, value) in page_config.items():
if isinstance(value, dict):
page_config[key] = [subkey for subkey in value if value[subkey]]

However, this is run before the attempted merge with serverapp data. So, if someone has set dict data for a key (e.g. "disabledExtensions" on the serverapp data, it gets clobbered by the (potentially empty) list from the settings dir.

Expected behavior

The conversion from dict to list happens after all merging has happened. As recursive_update does not merge lists, this seems the most reasonable option.

notFoundUrl pageConfig persisted

Description

notFoundUrl resent to browser with pageConfig with every JupyterLab load.

Reproduce

Expected behavior

  • Error message should be shown possibly once, and only if the non-existing URL was the initial JupyterLab URL being loaded.

Context

JupyterLab 3.4.8

Hi, while debugging some JupyterLab Desktop issues related to new features I am developing, I realized that jupyter server keeps returning previously not found URLs as part of pageConfig and that results in a dialog with the error message as shown below. If user mistakenly types an invalid path, this message would be shown at every JupyterLab reload since pageConfig persists the notFoundUrl config.

It seems to be caused by this line:

page_config["notFoundUrl"] = self.request.path

Also, if the non-existing path is part of initial URL entry then the popup is shown at that particular JupyterLab load. However, if the path was requested by javascript via fetch for example, then the popup will be shown at the subsequent JupyterLab loads, if any. The way I discovered the issue was, I opened dev tools and it requested source map file but couldn't load due to desktop app specific reasons, and next time I loaded JupyterLab it showed this "Path Not Found" error message.

I guess a solution could be to set page_config["notFoundUrl"] only for the initial JupyterLab URL load, if that was possible to detect.

jlab server path not found

Expose more file metadata about disk-backed content

As some new UI work for workspaces and settings is in-flight, it would be nice to offer some additional information about stuff stored on disk. The only thing that really jumps out at me (without adding a bunch of stuff like history/rollback), is the file-system level information, namely modified and created time. This would enable the UI to answer use cases like "find the settings i most recently changed " or "find the workspace I was working on last Tuesday"

It looks like a workspace already has a metadata field (id lives there), so adding a last_modified and created would be reasonable, presumably as ISO 8061 dates.

{"values: [{
  "data": {...},
  "metadata": {
    "id": "/lab",
    "created": "2020-07-21T00:19:20+0000",
    "last_modified": "2020-07-21T00:20:20+0000"
  }   
}]}

I guess these would be overwritten on import/export, with the on-disk time always winning.

The settings API response looks a little more complicated, and perhaps these could just be added to the top level of each member of the settings array.

{
  "settings": [{
    "id": "@foo/bar",
    "raw": "...",
    "settings": {...},
    "schema": {...},
    "version": "0.1.0",
    "created": "2020-07-21T00:19:20+0000",
    "last_modified": "2020-07-21T00:20:20+0000"
  }]
}

... or metadata could be added, with these in it, and eventually extended... though the buck has to stop somewhere, and I don't imagine much but sadness if settings carried anything not validated by the schema, or how it would get populated... HTTP headers?

Of course, open to any other suggestions of what might be hidden in there that would help folks navigate this stuff!

MathJax.js 404 error: c.ServerApp.base_url seems to be appended twice to file path

Hi, it seems that the c.ServerApp.base_url is appended twice to the MathJax.js path, which triggers a 404 error as follows:

[W 2021-01-23 22:44:29.913 ServerApp] 404 GET /base_url_path/base_url_path/static/notebook/components/MathJax/MathJax.js
?config=TeX-AMS-MML_HTMLorMML-full,Safe&delayStartupUntil=configured
(127.0.0.1) 92.81ms referer=https://server/base_url_path/lab/tree/...

Notice the base_url_path being appended twice to the path.

Jupyter Lab settings:

c.ServerApp.base_url = 'base_url_path'

Environment:

Ubuntu 20.04

jupyter                   1.0.0            py39hf3d152e_4    conda-forge
jupyter_client            6.1.11             pyhd8ed1ab_1    conda-forge
jupyter_console           6.2.0                      py_0    conda-forge
jupyter_core              4.7.0            py39hf3d152e_1    conda-forge
jupyter_server            1.2.2            py39hf3d152e_1    conda-forge
jupyterlab                3.0.5              pyhd8ed1ab_0    conda-forge
jupyterlab_server         2.1.2              pyhd8ed1ab_0    conda-forge

open_browser=False doesn't work anymore

Up until the new version 3 c.LabApp.open_browser = False used to work when starting jupyter-lab. The setting is now c.ServerApp.open_browser and it defaults to False but a browser window is opened every time I start jupyter-lab.

2.13.0: sphinx is failing because missing docs/autogen_config.py

Look slike sphinx is now failing because missing docs/autogen_config.py

Running Sphinx v4.5.0
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:123: PkgResourcesDeprecationWarning: 1.17.1-unknown is an invalid version and will not be supported in a future release
  warnings.warn(
making output directory... done

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/cmd/build.py", line 272, in build_main
    app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
  File "/usr/lib/python3.8/site-packages/sphinx/application.py", line 237, in __init__
    self.config.setup(self)
  File "/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.13.0/docs/source/conf.py", line 107, in setup
    exec(compile(f.read(), "../autogen_config.py", "exec"), {})
  File "../autogen_config.py", line 46, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.13.0/source/api/app-config.rst'

Exception occurred:
  File "../autogen_config.py", line 46, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.13.0/source/api/app-config.rst'
The full traceback has been saved in /tmp/sphinx-err-497h0cal.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!

Clarification - jupyterlab vs jupyterlab_launcher

I'm struggling to grasp what the conda package jupyterlab_launcher does in comparison to what jupyterlab does. The readme file was too technical for me to grasp while attempting to setup a minimalistic JupyterLab binder-enabled repo.

My observations

  • The conda package jupyterlab depends on the jupyterlab_launcher package.
  • The binder-examples/jupyterlab manages to startup JupyterLab with jupyterlab_launcher only.

Hardcoded logging level

Description

It seems that jupyterlab server is setting the logging level hardcoded to INFO:

logging.basicConfig(format="%(message)s", level=logging.INFO)

I was looking at a jupyter extension that was priting a lot of logs on the terminal, trying to find a way to silence these logs and I noticed the extension was using logging.info(), I assumed setting --log-level WARN would be enough but the logs kept appearing, eventually I found this code quoted above, I'm not 100% sure this is the culprit because its a lot of code to follow on but it seems the most likely.

Reproduce

  1. a jupyter extension that prints print(logging.getLogger())
  2. run jupyter lab --log-level WARN
  3. notice that the logger printed have the INFO log level <RootLogger root (INFO)>

I also tried jupyter lab --log-level WARN --Application.log_level=WARN --JupyterApp.log_level=WARN --ExtensionApp.log_level=WARN --LabServerApp.log_level=WARN --LabApp.log_level=WARN
with the same result.

Expected behavior

I expected that the --log-level command line args would set the logging to the requested log level

Context

  • Operating System and version: Ubuntu 20.04
  • Browser and version: Firefox 99
  • JupyterLab version: 3.3.4
  • JupyterLab server: 2.13.0
Troubleshoot Output
Paste the output from running `jupyter troubleshoot` from the command line here.
You may want to sanitize the paths in the output.
Command Line Output
Paste the output from your command line running `jupyter lab` here, use `--debug` if possible.
Browser Output
Paste the output from your browser Javascript console here, if applicable.

HTTP 500 on windows when schemas contain non-latin characters

On a particularly gruesome schema that includes non-latin characters in a settings schema, I encountered some 500 errors on windows. Patching those out, everything worked fine. Unfortunately I don't have logs available, but #103 (ft #102) demonstrates the condition on top of the soon-to-be-expanded test matrix.

Windows 10
conda 4.8.3
python=3.7.8=h60c2a47_0_cpython
jupyterlab=2.2.0=py_0
jupyterlab_server=1.2.0=py_0

Where is json_minify.py?

I've started packaging jupyterlab_server for Debian, and saw json_minify.py was MIT-licensed... but couldn't find that file : perhaps it was used at some point and the notice wasn't removed from LICENSE?

API specification and documentation

Just like Jupyter Server with the interactive Swagger UI documenting the API: https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/jupyter_server/master/jupyter_server/services/api/api.yaml#/

image

It would be nice if JupyterLab Server could provide something similar to document the extra endpoints such as settings and themes:

@default('workspaces_api_url')
def _default_workspaces_api_url(self):
return ujoin(self.app_url, 'api', 'workspaces/')
@default('settings_url')
def _default_settings_url(self):
return ujoin(self.app_url, 'api', 'settings/')
@default('listings_url')
def _default_listings_url(self):
return ujoin(self.app_url, 'api', 'listings/')
@default('themes_url')
def _default_themes_url(self):
return ujoin(self.app_url, 'api', 'themes/')
@default('tree_url')
def _default_tree_url(self):
return ujoin(self.app_url, 'tree/')
@default('translations_api_url')
def _default_translations_api_url(self):
return ujoin(self.app_url, 'api', 'translations/')

Maybe some static documentation might be enough as a start.

RFE: please upgrade for `mistune` 2.0.x

jupyterlab_server is not ready for mistune 2.0.x.

+ /usr/bin/sphinx-build -j48 -n -T -b man docs/source build/sphinx/man
Running Sphinx v5.2.1

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/cmd/build.py", line 274, in build_main
    app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
  File "/usr/lib/python3.8/site-packages/sphinx/application.py", line 223, in __init__
    self.setup_extension(extension)
  File "/usr/lib/python3.8/site-packages/sphinx/application.py", line 401, in setup_extension
    self.registry.load_extension(self, extname)
  File "/usr/lib/python3.8/site-packages/sphinx/registry.py", line 459, in load_extension
    mod = import_module(extname)
  File "/usr/lib64/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 843, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/usr/lib/python3.8/site-packages/sphinxcontrib/openapi/__init__.py", line 13, in <module>
    from sphinxcontrib.openapi import renderers, directive
  File "/usr/lib/python3.8/site-packages/sphinxcontrib/openapi/renderers/__init__.py", line 4, in <module>
    from ._httpdomain_old import HttpdomainOldRenderer
  File "/usr/lib/python3.8/site-packages/sphinxcontrib/openapi/renderers/_httpdomain_old.py", line 6, in <module>
    from .. import openapi20, openapi30, utils
  File "/usr/lib/python3.8/site-packages/sphinxcontrib/openapi/openapi20.py", line 16, in <module>
    from sphinxcontrib.openapi import utils
  File "/usr/lib/python3.8/site-packages/sphinxcontrib/openapi/utils.py", line 20, in <module>
    from m2r import convert as convert_markdown
  File "/usr/lib/python3.8/site-packages/m2r.py", line 58, in <module>
    class RestBlockGrammar(mistune.BlockGrammar):
AttributeError: module 'mistune' has no attribute 'BlockGrammar'

Exception occurred:
  File "/usr/lib/python3.8/site-packages/m2r.py", line 58, in <module>
    class RestBlockGrammar(mistune.BlockGrammar):
AttributeError: module 'mistune' has no attribute 'BlockGrammar'
The full traceback has been saved in /tmp/sphinx-err-2u8k8d98.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!

Serve fallback language

If a locale is es_CO and some translations are not there (which is pretty common when using variations), then the fallback es language pack should be used. Currently, the server is only serving es_CO (in this example). Need to also serve es.

(Note: variations of languages should have a dependency on the fallback.)

Cannot override settings by `null` value

Description

Our application uses jupyterlab's settings override feature to change the settings of some extensions.
However, due to an upgrade of jupyterlab_server (v2.5.2 => v2.12.0), the settings are no longer overridden.
From my investigation, settings are not overridden if the value is null, as in { "format": null }. This is probably because recursive_update used in the following location ignores properties with the value None.

recursive_update(overrides.setdefault(plugin_id, {}), config)

Reproduce

I faced this problem when overriding the jupyter-archive configuration. Therefore, below I describe how to reproduce the problem in the case of jupyter-archive. However, the same should be true for other settings as well.

  1. Install jupyter-archive extension
  2. Check the default setting of format is zip on Advanced Settings Editor
  3. Add sys.prefix>/local/share/jupyter/lab/settings/overrides.json and see below for the contents of this file
  4. Check that the default setting of format is not overridden
    (5. If you set non-null value like tgz, it works well)

Expected behavior

In previous versions of jupyterlab_server, setting values could be overridden with null. Newer versions should be able to do the same, I think.

Context

  • JupyterLab version: 3.0.16
  • jupyterlab_server that worked well: 2.5.2
  • jupyterlab_server that does not work well: 2.12.0

Release with Listings Handler

Hi, #82 has just been merged and provides an additional Handler for the Listings.

There is no breaking change and previous jupyterlab version will continue to work transparently with that change.

For JupyterLab 2.1 release, we need a release of jupyterlab_server with that change.

Latest version is 1.0.7. I am not sure what version policy to apply here, but my feeling is that going to 1.0.8 is OK.

Can someone pick this?

URL handling cleanup

  • Normalize paths to handle leading and trailing slashes (e.g.default_url, base_url)
  • Get rid of page_url in favor of the existing default_url
  • Rename publicUrl -> staticUrl
  • Rename frontendUrl -> fullStaticUrl
  • If base_url is included, prepend a field with full, eg: * fullStaticUrl * fullMathjaxUrl
  • change from /lab/static/ to /static/lab in preparation for jupyter-server/jupyter_server#48

This requires a coordinated change with Jupyterlab and should be in a 1.0alpha version of this library

Move WIP license reporting here from core?

Over on jupyterlab/jupyterlab#9779 I've started some work to make frontend library license reporting more structured. The current alpha release includes a third-party-licenses.txt, but the baseline report is pretty simple. That PR moves the reporting to a predictable third-party-license.json structure (even have a schema, but got rid of it) generated by a single codepath in @jupyterlab/builder, and on top of it builds:

  • an API endpoint /lab/api/licenses
  • a CLI tool jupyter lab licenses

...with all the fixin's: different output formats, etc.

Those things would be fine to land there, exclusively, but license compliance seems a thing that is probably even more important to downstream Lab-derived applications. Also, the federated_modules data definitions live over here, which is a pretty important piece.

If this happened, that PR would probably split into:

  • jupyterlab/jupyterlab
    • @jupyterlab/builder dev tool which generates third-party-licenses.json
    • @jupyterlab/licenses-extension which consumes the API
  • jupyterlab/jupyterlab_server
    • the LicensesManager and LicensesHandler
  • not sure
    • the LabLicensesApp for the CLI
      • might be nice to have here for folks to subclass

Any thoughts appreciated!

2.16.4: sphinx fails because incorrect path to app-config.rst and `reference target not found` sphinx warnings

Looks like docs/source/ content needs some updates

[tkloczko@pers-jacek jupyterlab_server-2.16.4]$ PYTHONPATH=$PWD /usr/bin/sphinx-build -n -T -b man docs/source build/sphinx/man
Running Sphinx v5.3.0
/usr/lib/python3.8/site-packages/pkg_resources/__init__.py:123: PkgResourcesDeprecationWarning: 1.17.1-unknown is an invalid version and will not be supported in a future release
  warnings.warn(

Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/sphinx/cmd/build.py", line 276, in build_main
    app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
  File "/usr/lib/python3.8/site-packages/sphinx/application.py", line 237, in __init__
    self.config.setup(self)
  File "/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.4/docs/source/conf.py", line 108, in setup
    exec(compile(f.read(), "../autogen_config.py", "exec"), {})  # noqa
  File "../autogen_config.py", line 46, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.4/source/api/app-config.rst'

Exception occurred:
  File "../autogen_config.py", line 46, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.4/source/api/app-config.rst'
The full traceback has been saved in /tmp/sphinx-err-msv5x255.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!

Instead of injecting PYTHONPATH=$PWD could be applied patch like below

--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -9,10 +9,10 @@
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-# import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
+import os
+import sys
+sys.path.insert(0, os.path.abspath("../.."))
+
 import os.path as osp
 import shutil
 import sys

This patch does exactly what is mentioned in comment above that code.

CP949 encoding error on Windows

Reproduce

  1. Install JupyterLab by pip (This stage doens't outputs error below)
  2. Install jupyterlab-kite by pip
  3. Luanch JupyterLab (The error occurs here)
  4. (Install jupyterlab_kite extension by jupyter labextension install "@kiteco/jupyterlab-kite")
  • Windows 10
  • jupyterlab==3.0.7
  • jupyter-server==1.2.2
  • jupyterlab-kite==2.0.2

Error Message

This is similar issue of JupyterLab issue #9171.

And the actual error output is:

      File "f:\develop\.venv\lib\site-packages\jupyterlab_server\config.py", line 37, in get_federated_extensions
        pkgdata = json.load(fid)
      File "C:\Users\takanori\AppData\Local\Programs\Python\Python37\lib\json\__init__.py", line 293, in load
        return loads(fp.read(),
    UnicodeDecodeError: 'cp932' codec can't decode byte 0x82 in position 523: illegal multibyte sequence

Solution

I could fix this issue by altering the line as: (I added encoding= argument.)

def get_federated_extensions(labextensions_path):
    ~~~
            with open(ext_path, encoding="utf-8") as fid:
                pkgdata = json.load(fid)
    ~~~

I pushed the fixed code on my forked repo.

Conda-Forge Installation Error

Hi, I have been trying to update my jupyter-server in my conda environment as one of the dependencies of another package. However, the installation of the package failed as shown below:

image

Is there any workaround to this?

rendering seem borked after 0.5.5 -> 0.6 upgrade

I just upgraded jupyterlab_launcher from 0.5.5 to 0.6 this morning. And after restarting jupyter-lab I was greeted with the following:

screen shot 2017-12-04 at 9 55 14

After downgrading to 0.5.5 things looked normal again:

screen shot 2017-12-04 at 9 55 34

The upgrade was done via pip3 install -U jupyterlab_launcher. Is there something else that needs to be done or?

For reference:

pip3 list | grep jupyter
jupyter-client (5.1.0)
jupyter-core (4.4.0)
jupyterlab (0.29.2)
jupyterlab-launcher (0.5.5)

2.16.0: pytest is failing

I'm packaging your module as an rpm package so I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.

  • python3 -sBm build -w --no-isolation
  • because I'm calling build with --no-isolation I'm using during all processes only locally installed modules
  • install .whl file in </install/prefix>
  • run pytest with PYTHONPATH pointing to sitearch and sitelib inside </install/prefix>

Here is pytest output:

+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-jupyterlab-server-2.16.0-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-jupyterlab-server-2.16.0-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra -qq

================================================================================== ERRORS ==================================================================================
__________________________________________________________________ ERROR collecting tests/test_labapp.py ___________________________________________________________________
tests/test_labapp.py:7: in <module>
    from jupyterlab_server.test_utils import expected_http_error
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:168: in exec_module
    exec(co, module.__dict__)
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
__________________________________________________________________ ERROR collecting tests/test_labapp.py ___________________________________________________________________
ImportError while importing test module '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.0/tests/test_labapp.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_labapp.py:7: in <module>
    from jupyterlab_server.test_utils import expected_http_error
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
_______________________________________________________________ ERROR collecting tests/test_listings_api.py ________________________________________________________________
tests/test_listings_api.py:1: in <module>
    from jupyterlab_server.test_utils import validate_request
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:168: in exec_module
    exec(co, module.__dict__)
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
_______________________________________________________________ ERROR collecting tests/test_listings_api.py ________________________________________________________________
ImportError while importing test module '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.0/tests/test_listings_api.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_listings_api.py:1: in <module>
    from jupyterlab_server.test_utils import validate_request
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
_______________________________________________________________ ERROR collecting tests/test_settings_api.py ________________________________________________________________
tests/test_settings_api.py:11: in <module>
    from jupyterlab_server.test_utils import (
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:168: in exec_module
    exec(co, module.__dict__)
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
_______________________________________________________________ ERROR collecting tests/test_settings_api.py ________________________________________________________________
ImportError while importing test module '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.0/tests/test_settings_api.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_settings_api.py:11: in <module>
    from jupyterlab_server.test_utils import (
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
________________________________________________________________ ERROR collecting tests/test_themes_api.py _________________________________________________________________
tests/test_themes_api.py:1: in <module>
    from jupyterlab_server.test_utils import validate_request
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:168: in exec_module
    exec(co, module.__dict__)
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
________________________________________________________________ ERROR collecting tests/test_themes_api.py _________________________________________________________________
ImportError while importing test module '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.0/tests/test_themes_api.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_themes_api.py:1: in <module>
    from jupyterlab_server.test_utils import validate_request
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
______________________________________________________________ ERROR collecting tests/test_translation_api.py ______________________________________________________________
tests/test_translation_api.py:11: in <module>
    from jupyterlab_server.test_utils import maybe_patch_ioloop, validate_request
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:168: in exec_module
    exec(co, module.__dict__)
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
______________________________________________________________ ERROR collecting tests/test_translation_api.py ______________________________________________________________
ImportError while importing test module '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.0/tests/test_translation_api.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_translation_api.py:11: in <module>
    from jupyterlab_server.test_utils import maybe_patch_ioloop, validate_request
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
______________________________________________________________ ERROR collecting tests/test_workspaces_api.py _______________________________________________________________
tests/test_workspaces_api.py:9: in <module>
    from jupyterlab_server.test_utils import (
/usr/lib/python3.8/site-packages/_pytest/assertion/rewrite.py:168: in exec_module
    exec(co, module.__dict__)
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
______________________________________________________________ ERROR collecting tests/test_workspaces_api.py _______________________________________________________________
ImportError while importing test module '/home/tkloczko/rpmbuild/BUILD/jupyterlab_server-2.16.0/tests/test_workspaces_api.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_workspaces_api.py:9: in <module>
    from jupyterlab_server.test_utils import (
jupyterlab_server/test_utils.py:11: in <module>
    from openapi_core.validation.request.datatypes import OpenAPIRequest, RequestParameters
/usr/lib/python3.8/site-packages/openapi_core/__init__.py:3: in <module>
    from openapi_core.shortcuts import (
/usr/lib/python3.8/site-packages/openapi_core/shortcuts.py:3: in <module>
    from openapi_core.spec.shortcuts import create_spec
/usr/lib/python3.8/site-packages/openapi_core/spec/shortcuts.py:3: in <module>
    from openapi_spec_validator import (
E   ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__init__.py)
========================================================================= short test summary info ==========================================================================
ERROR tests/test_labapp.py - ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validator/__...
ERROR tests/test_labapp.py
ERROR tests/test_listings_api.py - ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_valida...
ERROR tests/test_listings_api.py
ERROR tests/test_settings_api.py - ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_valida...
ERROR tests/test_settings_api.py
ERROR tests/test_themes_api.py - ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_validato...
ERROR tests/test_themes_api.py
ERROR tests/test_translation_api.py - ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_val...
ERROR tests/test_translation_api.py
ERROR tests/test_workspaces_api.py - ImportError: cannot import name 'default_handlers' from 'openapi_spec_validator' (/usr/lib/python3.8/site-packages/openapi_spec_vali...
ERROR tests/test_workspaces_api.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 12 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Here is list of installed modules in build env

Package                       Version
----------------------------- -----------------
alabaster                     0.7.12
anyio                         3.6.1
appdirs                       1.4.4
argon2-cffi                   21.3.0
argon2-cffi-bindings          21.2.0
attrs                         22.1.0
autodoc-traits                0.1.0
Babel                         2.10.2
beautifulsoup4                4.11.1
bleach                        5.0.0
Brlapi                        0.8.3
build                         0.8.0
cffi                          1.15.1
charset-normalizer            2.1.0
codespell                     2.2.1
cssselect                     1.1.0
decorator                     5.1.1
defusedxml                    0.7.1
deprecation                   2.1.0
distro                        1.7.0
dnspython                     2.2.1
docutils                      0.18.1
editables                     0.3
entrypoints                   0.4
extras                        1.0.0
fastjsonschema                2.16.1
fixtures                      4.0.0
freezegun                     1.2.1
gpg                           1.17.1-unknown
hatchling                     1.11.0
html5lib                      1.1
idna                          3.4
imagesize                     1.4.1
importlib-metadata            5.0.0
importlib-resources           5.9.0
iniconfig                     1.1.1
isodate                       0.6.1
Jinja2                        3.1.1
json5                         0.9.9
jsonschema                    4.16.0
jsonschema-spec               0.1.2
jupyter_client                7.4.2
jupyter_core                  4.11.1
jupyter_packaging             0.12.3
jupyter-server                1.21.0
jupyterlab-pygments           0.1.2
lazy-object-proxy             1.7.1
libcomps                      0.1.19
louis                         3.23.0
lxml                          4.9.1
m2r                           0.2.1
markdown-it-py                2.1.0
MarkupSafe                    2.1.1
mdit-py-plugins               0.3.1
mdurl                         0.1.1
mistune                       2.0.4
more-itertools                8.14.0
myst-parser                   0.18.0
nbclient                      0.7.0
nbconvert                     7.2.1
nbformat                      5.7.0
nest-asyncio                  1.5.6
numpy                         1.23.1
numpydoc                      1.5.0
openapi-core                  0.14.2
openapi-schema-validator      0.3.4
openapi-spec-validator        0.5.1
packaging                     21.3
pandocfilters                 1.5.0
parse                         1.19.0
pathable                      0.4.3
pathspec                      0.10.1
pbr                           5.9.0
pep517                        0.12.0
pip                           22.2.2
pkgutil_resolve_name          1.3.10
pluggy                        1.0.0
ply                           3.11
prometheus-client             0.14.1
ptyprocess                    0.7.0
py                            1.11.0
pycparser                     2.21
Pygments                      2.13.0
PyGObject                     3.42.2
pyparsing                     3.0.9
pyrsistent                    0.18.1
pytest                        7.1.3
pytest-runner                 6.0.0
pytest-timeout                2.1.0
pytest-tornasync              0.6.0.post2
python-dateutil               2.8.2
pytz                          2022.4
PyYAML                        6.0
pyzmq                         24.0.0
requests                      2.28.1
rpm                           4.17.0
ruamel.yaml                   0.17.21
ruamel.yaml.clib              0.2.6
scour                         0.38.2
Send2Trash                    1.8.0
setuptools                    65.4.1
six                           1.16.0
sniffio                       1.2.0
snowballstemmer               2.2.0
soupsieve                     2.3.2.post1
Sphinx                        5.2.3
sphinx-copybutton             0.5.0
sphinxcontrib-applehelp       1.0.2.dev20220730
sphinxcontrib-devhelp         1.0.2.dev20220730
sphinxcontrib-htmlhelp        2.0.0
sphinxcontrib-httpdomain      1.8.0
sphinxcontrib-jsmath          1.0.1.dev20220730
sphinxcontrib-openapi         0.7.0
sphinxcontrib-qthelp          1.0.3.dev20220730
sphinxcontrib-serializinghtml 1.1.5
strict-rfc3339                0.7
terminado                     0.15.0
testtools                     2.5.0
text-unidecode                1.3
tinycss2                      1.1.1
tomli                         2.0.1
tomlkit                       0.11.5
tornado                       6.2
traitlets                     5.4.0
typing_extensions             4.3.0
urllib3                       1.26.12
validators                    0.20.0
webencodings                  0.5.1
websocket-client              1.4.1
Werkzeug                      2.2.2
wheel                         0.37.1
zipp                          3.9.0

Inject page config on a per-request basis

Problem

When running in JupyterHub, we would like to inject some fields to page config that are based on the incoming request (e.g. based on the authenticated user, which can vary from one request to the next). However, the way page config is populated in LabHandler.get makes it hard to find a hook to add/modify fields.

Proposed Solution

Add a hook for 'extra page config' that can be a callable, so that page config can be extended. Possibly this could be discovered via jupyter-server extensions, so that each extension could add its own page config? For us, at least some mechanism would need to to take the current request into account.

What would suffice for us:

page_config = ...
# apply extra page config hook
if self.settings.get("extra_page_config", None):
    page_config = self.settings["extra_page_config"](self, copy.copy(page_config))
... # continue as before

but just one hook might not suffice if multiple extensions also want to do this. I'm not sure they will, though, because extensions generally have their own place to put settings. JupyterHub does need to modify the root page config itself.

Additional context

JupyterHub's server-extension code where we would call this hook is here. We generally inject some things into Jupyter handler base classes. I'd like to do this via existing extension APIs as much as possible. Ultimately, I'd like to get to the point where jupyterhub-singleuser is implemented as a Jupyter Server Extension, but the necessary extension points don't exist yet.

Fix setting registry warnings

Most likely introduced in #109

cf jupyterlab/jupyterlab-module-federation#42

Notes from @afshin:

  1. we need the schema field to come through in the settings response from the server
  2. it doesn't exist so it's warning you about that error
  3. the server doesn't require schema to exist
  4. the specific plugin whose schema appears to not exist is "@jupyterlab/tooltip-extension:notebooks"
  5. there is nothing obviously wrong with schema/notebooks.json in the tooltips-extension

Installation error, WinError 206, The filename or exertion is too long.

Hi,

Recently, I tried to install JupyterLab using pip on my new work laptop running Windows 10. While installing jupyterlab-server, the following error popped-up:

Installing collected packages: jupyterlab-server
ERROR: Could not install packages due to an EnvironmentError: [WinError 206] The filename or extension is too long: 'C:\\Users\\xxxx\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python39\\site-packages\\jupyterlab_server\\tests\\translations\\jupyterlab-language-pack-es_CO\\jupyterlab_language_pack_es_CO\\locale\\es_CO'

The laptop being locked up by our IT department, no chance to unlock the 260 characters path limit.

Solution

  • Clone this git
  • Remove the test folder
  • pip install from files

Better solutions ?

Are these tests really necessary ?
If so, any chance to rename/re-structure them to avoid this problem ?

Thanks

Unable to open a kernel if HTTP PATCH request is blocked by proxy

This is a continuation of jupyterlab/jupyterlab#8196, with jupyterlab 2.0.1 and jupyterlab-server 1.0.7 I wasn't able to rename anything but nothing was preventing me from using JupyterLab.

Now with jupyter-server 1.3.0 I cannot open a kernel, the following HTTP request

PATCH | http://{IP}/user/{user}/api/sessions/e63b7989-39a6-434f-918d-68be34178f9e?1614252567276=
with data: {"path":"Untitled.ipynb","id":"e63b7989-39a6-434f-918d-68be34178f9e"}

yields:

HTTP/ 405 Method Not Allowed
Mime-Version: 1.0
Date: Thu, 25 Feb 2021 12:29:27 CET
Via:  proxy:8080
Content-Type: text/html
Connection: close
Content-Length: 28

Page could not be displayed.

So JupyterLab in this context is unusable, and I had no luck asking to relax the policies of my corporate proxy unfortunately.

Will you please consider a workaround incase PATCH request are blocked, falling back to GET/POST possibly ?
Thank you.

Customer settings for static url

Now the static URL is constructed from base_url /lab and /static, and is not friendly for CDN.
Could it be moved into custom settings?

v2.0.0: 'NotebookWebApplication' object has no attribute 'append'

Downgrading to jupyterlab-server==1.2.0 works. Here's the stack of the error:

jupyter lab --no-browser --port=8888 --ip=0.0.0.0
[I 23:36:06.549 LabApp] Writing notebook server cookie secret to /home/vagrant/.local/share/jupyter/runtime/notebook_cookie_secret
[I 23:36:07.049 LabApp] JupyterLab extension loaded from /home/vagrant/.pyenv/versions/3.7.2/envs/py3/lib/python3.7/site-packages/jupyterlab
[I 23:36:07.049 LabApp] JupyterLab application directory is /home/vagrant/.pyenv/versions/3.7.2/envs/py3/share/jupyter/lab
zzzz[W 23:36:07.051 LabApp] Error loading server extension jupyterlab
    Traceback (most recent call last):
      File "/home/vagrant/.pyenv/versions/3.7.2/envs/py3/lib/python3.7/site-packages/notebook/notebookapp.py", line 1991, in init_server_extensions
        func(self)
      File "/home/vagrant/.pyenv/versions/3.7.2/envs/py3/lib/python3.7/site-packages/jupyterlab/extension.py", line 222, in load_jupyter_server_extension
        add_handlers(web_app, config)
      File "/home/vagrant/.pyenv/versions/3.7.2/envs/py3/lib/python3.7/site-packages/jupyterlab_server/handlers.py", line 165, in add_handlers
        handlers.append((url_pattern, LabHandler))
    AttributeError: 'NotebookWebApplication' object has no attribute 'append'

Is there a way to change the Cache-Control header?

Hey!

I tried to modify the Cache-Control header though the server_extension, but it always got over-written.

class CacheHandler(web.RequestHandler):
  def get(self):
        self.set_header('Cache-Control', 'max-age=31536000000')

app = Application([
    (r'/static/lab/(.*)', CacheHandler)
    ])

Did I miss anything?

Instructions on how to run tests

Hi!

As far as I can see, there are no instructions on how to run the tests. There is CI set up, as far as I can see, but trying to reproduce the setup in a virtual environment and a call to pytest has failed me:

$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -e .
... (takes a little while) ...
$ pytest
bash: pytest: command not found

So I will install pytest:

$ pip install pytest
$ pytest
Traceback (most recent call last):
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 703, in import_plugin
    __import__(importspec)
ModuleNotFoundError: No module named 'pytest_tornasync'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/bin/pytest", line 8, in <module>
    sys.exit(console_main())
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 187, in console_main
    code = main()
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 143, in main
    config = _prepareconfig(args, plugins)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 318, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/pluggy/callers.py", line 203, in _multicall
    gen.send(outcome)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/helpconfig.py", line 100, in pytest_cmdline_parse
    config = outcome.get_result()  # type: Config
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1003, in pytest_cmdline_parse
    self.parse(args)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1280, in parse
    self._preparse(args, addopts=addopts)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1172, in _preparse
    self.pluginmanager.load_setuptools_entrypoints("pytest11")
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/pluggy/manager.py", line 300, in load_setuptools_entrypoints
    self.register(plugin, name=ep.name)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 443, in register
    self.consider_module(plugin)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 669, in consider_module
    self._import_plugin_specs(getattr(mod, "pytest_plugins", []))
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 676, in _import_plugin_specs
    self.import_plugin(import_spec)
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 705, in import_plugin
    raise ImportError(
  File "/home/user/dev/python/jupyter/jupyterlab_server/venv/lib/python3.8/site-packages/_pytest/config/__init__.py", line 703, in import_plugin
    __import__(importspec)
ImportError: Error importing plugin "pytest_tornasync": No module named 'pytest_tornasync'

So I will install install pytest-tornasync:

$ pip install pytest-tornasync
$ pytest
ERROR: usage: pytest [options] [file_or_dir] [file_or_dir] [...]
pytest: error: unrecognized arguments: --cov jupyterlab_server --cov-report term-missing --cov-report term:skip-covered
  inifile: /home/user/dev/python/jupyter/jupyterlab_server/setup.cfg
  rootdir: /home/user/dev/python/jupyter/jupyterlab_server

Another attempt:

$ python setup.py test
running test
WARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox.
running egg_info
writing jupyterlab_server.egg-info/PKG-INFO
writing dependency_links to jupyterlab_server.egg-info/dependency_links.txt
writing entry points to jupyterlab_server.egg-info/entry_points.txt
writing requirements to jupyterlab_server.egg-info/requires.txt
writing top-level names to jupyterlab_server.egg-info/top_level.txt
reading manifest file 'jupyterlab_server.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*~' found anywhere in distribution
warning: no previously-included files matching '*.pyc' found anywhere in distribution
warning: no previously-included files matching '*.pyo' found anywhere in distribution
warning: no previously-included files matching '.git' found anywhere in distribution
warning: no previously-included files matching '.ipynb_checkpoints' found anywhere in distribution
writing manifest file 'jupyterlab_server.egg-info/SOURCES.txt'
running build_ext
test_settings_api (unittest.loader._FailedTest) ... ERROR
test_workspaces_api (unittest.loader._FailedTest) ... ERROR
jupyterlab_server.tests.test_settings_api (unittest.loader._FailedTest) ... ERROR
jupyterlab_server.tests.test_workspaces_api (unittest.loader._FailedTest) ... ERROR

======================================================================
ERROR: test_settings_api (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_settings_api
Traceback (most recent call last):
  File "/usr/lib/python3.8/unittest/loader.py", line 154, in loadTestsFromName
    module = __import__(module_name)
  File "/home/user/dev/python/jupyter/jupyterlab_server/jupyterlab_server/tests/test_settings_api.py", line 9, in <module>
    from strict_rfc3339 import rfc3339_to_timestamp
ModuleNotFoundError: No module named 'strict_rfc3339'


======================================================================
ERROR: test_workspaces_api (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_workspaces_api
Traceback (most recent call last):
  File "/usr/lib/python3.8/unittest/loader.py", line 154, in loadTestsFromName
    module = __import__(module_name)
  File "/home/user/dev/python/jupyter/jupyterlab_server/jupyterlab_server/tests/test_workspaces_api.py", line 8, in <module>
    from strict_rfc3339 import rfc3339_to_timestamp
ModuleNotFoundError: No module named 'strict_rfc3339'


======================================================================
ERROR: jupyterlab_server.tests.test_settings_api (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: jupyterlab_server.tests.test_settings_api
Traceback (most recent call last):
  File "/usr/lib/python3.8/unittest/loader.py", line 436, in _find_test_path
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
    __import__(name)
  File "/home/user/dev/python/jupyter/jupyterlab_server/jupyterlab_server/tests/test_settings_api.py", line 9, in <module>
    from strict_rfc3339 import rfc3339_to_timestamp
ModuleNotFoundError: No module named 'strict_rfc3339'


======================================================================
ERROR: jupyterlab_server.tests.test_workspaces_api (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: jupyterlab_server.tests.test_workspaces_api
Traceback (most recent call last):
  File "/usr/lib/python3.8/unittest/loader.py", line 436, in _find_test_path
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
    __import__(name)
  File "/home/user/dev/python/jupyter/jupyterlab_server/jupyterlab_server/tests/test_workspaces_api.py", line 8, in <module>
    from strict_rfc3339 import rfc3339_to_timestamp
ModuleNotFoundError: No module named 'strict_rfc3339'


----------------------------------------------------------------------
Ran 4 tests in 0.000s

FAILED (errors=4)
Test failed: <unittest.runner.TextTestResult run=4 errors=4 failures=0>
error: Test failed: <unittest.runner.TextTestResult run=4 errors=4 failures=0>

OK one more to install:

$ pip install strict-rfc3339
$ python setup.py test
running test
WARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox.
running egg_info
writing jupyterlab_server.egg-info/PKG-INFO
writing dependency_links to jupyterlab_server.egg-info/dependency_links.txt
writing entry points to jupyterlab_server.egg-info/entry_points.txt
writing requirements to jupyterlab_server.egg-info/requires.txt
writing top-level names to jupyterlab_server.egg-info/top_level.txt
reading manifest file 'jupyterlab_server.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*~' found anywhere in distribution
warning: no previously-included files matching '*.pyc' found anywhere in distribution
warning: no previously-included files matching '*.pyo' found anywhere in distribution
warning: no previously-included files matching '.git' found anywhere in distribution
warning: no previously-included files matching '.ipynb_checkpoints' found anywhere in distribution
writing manifest file 'jupyterlab_server.egg-info/SOURCES.txt'
running build_ext

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

I also tried the following:

$ pip install -e .[test]
$ python setup.py test
running test
WARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox.
running egg_info
writing jupyterlab_server.egg-info/PKG-INFO
writing dependency_links to jupyterlab_server.egg-info/dependency_links.txt
writing entry points to jupyterlab_server.egg-info/entry_points.txt
writing requirements to jupyterlab_server.egg-info/requires.txt
writing top-level names to jupyterlab_server.egg-info/top_level.txt
reading manifest file 'jupyterlab_server.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*~' found anywhere in distribution
warning: no previously-included files matching '*.pyc' found anywhere in distribution
warning: no previously-included files matching '*.pyo' found anywhere in distribution
warning: no previously-included files matching '.git' found anywhere in distribution
warning: no previously-included files matching '.ipynb_checkpoints' found anywhere in distribution
writing manifest file 'jupyterlab_server.egg-info/SOURCES.txt'
running build_ext

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

And I am out of ideas. Not running any tests is probably not the idea, so my invokation must be not the intended way.

I am not sure what else to conclude from here https://github.com/jupyterlab/jupyterlab_server/actions/runs/191916555/workflow and how to make the tests run locally on my system.

I would like to at least once run the tests successfully, on my local machine. The background is, that I am trying to figure out, how to make a jupyterlab setup in a Guix package manager environment. There I am as far as it automatically running the tests, but then failing at the test_workspaces_api tests and I want to confirm whether that is because of the setup inside GNU Guix package manager, or because the tests are really failing in their current state. However, I cannot claim, that the tests are failing, without knowing what kind of test environment they can run in, on my own machine, not in some CI.

It would be great to have some test environment preparation script (or is that already pip install -e .[test]?) or at least a requirements file, which will install everything in the correct version.

Can anyone help me out?

Edit:

I seem to have gotten it now finally. After running pip install -e .[test], then I need to call pytest!

===================================================================== test session starts ======================================================================
platform linux -- Python 3.8.5, pytest-5.3.2, py-1.9.0, pluggy-0.13.1 -- /home/user/dev/python/jupyter/jupyterlab_server/venv/bin/python3
cachedir: .pytest_cache
rootdir: /home/user/dev/python/jupyter/jupyterlab_server, inifile: setup.cfg
plugins: jupyter-server-1.0.5, tornasync-0.6.0.post2, console-scripts-1.0.0, cov-2.10.1, jupyterlab-server-2.0.0rc1
collected 38 items                                                                                                                                             

jupyterlab_server/tests/test_labapp.py::test_lab_handler [D 2020-10-19 22:42:30.971 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_labapp.py::test_notebook_handler [D 2020-10-19 22:42:31.072 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_labapp.py::test_404 [D 2020-10-19 22:42:31.129 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_get [D 2020-10-19 22:42:31.180 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_get_federated [D 2020-10-19 22:42:31.227 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_get_bad [D 2020-10-19 22:42:31.271 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_listing [D 2020-10-19 22:42:31.318 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_patch [D 2020-10-19 22:42:31.373 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_patch_unicode [D 2020-10-19 22:42:31.473 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_patch_wrong_id [D 2020-10-19 22:42:31.549 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_patch_bad_data [D 2020-10-19 22:42:31.599 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_settings_api.py::test_patch_invalid_payload_format [D 2020-10-19 22:42:31.647 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
[W 2020-10-19 22:42:31.681 LabServerApp] Invalid format for JSON payload. Must be in the form {'raw': ...}
[W 2020-10-19 22:42:31.682 LabServerApp] 400 PUT /lab/api/settings/%40jupyterlab/apputils-extension%3Athemes (127.0.0.1) 2.13ms referer=None
PASSED
jupyterlab_server/tests/test_settings_api.py::test_patch_invalid_json [D 2020-10-19 22:42:31.691 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
[W 2020-10-19 22:42:31.730 LabServerApp] Invalid format for JSON payload. Must be in the form {'raw': ...}
[W 2020-10-19 22:42:31.730 LabServerApp] 400 PUT /lab/api/settings/%40jupyterlab/apputils-extension%3Athemes (127.0.0.1) 2.11ms referer=None
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get Processing ./jupyterlab_server/tests/translations/jupyterlab-some-package
Building wheels for collected packages: jupyterlab-some-package
  Building wheel for jupyterlab-some-package (setup.py) ... done
  Created wheel for jupyterlab-some-package: filename=jupyterlab_some_package-0.1.0-py3-none-any.whl size=2086 sha256=e977ad42da305de056119e94188a21683c350336da1909ec676791a2717a1e32
  Stored in directory: /home/user/.cache/pip/wheels/21/a6/6d/e8039b49be7427d2ca75234f5f309b667d62e7fdadf33e7f8e
Successfully built jupyterlab-some-package
Installing collected packages: jupyterlab-some-package
Successfully installed jupyterlab-some-package-0.1.0
Processing ./jupyterlab_server/tests/translations/jupyterlab-language-pack-es_CO
Building wheels for collected packages: jupyterlab-language-pack-es-CO
  Building wheel for jupyterlab-language-pack-es-CO (setup.py) ... done
  Created wheel for jupyterlab-language-pack-es-CO: filename=jupyterlab_language_pack_es_CO-0.1.0-py3-none-any.whl size=2541 sha256=5b6008acbf4950e09838dc3b0794b8c6f954e68c35323328e5a07c0668c97217
  Stored in directory: /home/user/.cache/pip/wheels/87/a4/6b/e87225984fd86439e5df4dba7e8d42e146d33d6ce684cc73e1
Successfully built jupyterlab-language-pack-es-CO
Installing collected packages: jupyterlab-language-pack-es-CO
Successfully installed jupyterlab-language-pack-es-CO-0.1.0
[D 2020-10-19 22:42:34.652 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_locale [D 2020-10-19 22:42:34.861 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_locale_bad [D 2020-10-19 22:42:35.186 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_locale_not_installed [D 2020-10-19 22:42:35.510 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_locale_not_valid [D 2020-10-19 22:42:35.829 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_installed_language_pack_locales_fails [D 2020-10-19 22:42:36.157 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_installed_language_pack_locales_passes [D 2020-10-19 22:42:36.199 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_installed_package_locales_fails [D 2020-10-19 22:42:36.386 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_installed_package_locales [D 2020-10-19 22:42:36.447 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_installed_packages_locale [D 2020-10-19 22:42:36.631 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_language_packs [D 2020-10-19 22:42:36.810 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_language_pack [D 2020-10-19 22:42:36.990 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_merge_locale_data [D 2020-10-19 22:42:37.309 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_is_valid_locale_valid [D 2020-10-19 22:42:37.349 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_is_valid_locale_invalid [D 2020-10-19 22:42:37.387 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_display_name_valid [D 2020-10-19 22:42:37.428 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_translation_api.py::test_get_display_name_invalid [D 2020-10-19 22:42:37.473 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSEDFound existing installation: jupyterlab-some-package 0.1.0
Uninstalling jupyterlab-some-package-0.1.0:
  Successfully uninstalled jupyterlab-some-package-0.1.0
Found existing installation: jupyterlab-language-pack-es-CO 0.1.0
Uninstalling jupyterlab-language-pack-es-CO-0.1.0:
  Successfully uninstalled jupyterlab-language-pack-es-CO-0.1.0

jupyterlab_server/tests/test_workspaces_api.py::test_delete [D 2020-10-19 22:42:39.041 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_workspaces_api.py::test_get_non_existant [D 2020-10-19 22:42:39.084 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_workspaces_api.py::test_get [D 2020-10-19 22:42:39.134 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_workspaces_api.py::test_listing [D 2020-10-19 22:42:39.176 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_workspaces_api.py::test_listing_dates [D 2020-10-19 22:42:39.215 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_workspaces_api.py::test_put [D 2020-10-19 22:42:39.257 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
PASSED
jupyterlab_server/tests/test_workspaces_api.py::test_bad_put [D 2020-10-19 22:42:39.298 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
[W 2020-10-19 22:42:39.332 LabServerApp] Workspace metadata ID mismatch: expected 'bar' got '/foo'
[W 2020-10-19 22:42:39.332 LabServerApp] 400 PUT /lab/api/workspaces/bar (127.0.0.1) 0.63ms referer=None
PASSED
jupyterlab_server/tests/test_workspaces_api.py::test_blank_put [D 2020-10-19 22:42:39.341 ServerApp] Config changed: {'NotebookNotary': {'db_file': ':memory:'}}
[W 2020-10-19 22:42:39.376 LabServerApp] Workspace name is required for PUT.
[W 2020-10-19 22:42:39.376 LabServerApp] 400 PUT /lab/api/workspaces (127.0.0.1) 0.69ms referer=None
PASSED

----------- coverage: platform linux, python 3.8.5-final-0 -----------
Name                                              Stmts   Miss  Cover   Missing
-------------------------------------------------------------------------------
jupyterlab_server/__init__.py                         7      7     0%   4-21
jupyterlab_server/_version.py                         2      2     0%   1-2
jupyterlab_server/app.py                             44     38    14%   2-26, 29-94, 98, 103, 106
jupyterlab_server/config.py                         133    101    24%   2-27, 34-40, 44, 55-69, 74, 85-103, 107-109, 119-194, 197-198, 201-206, 209-210, 213-214, 217-218, 221-226, 229-230
jupyterlab_server/handlers.py                       147     45    69%   2-48, 56-66, 102, 132-133, 140, 157, 159, 220-222, 230, 232, 237-243, 249-251, 279
jupyterlab_server/listings_handler.py                44     38    14%   6-23, 28-35, 37-44, 53-82
jupyterlab_server/process.py                        150    150     0%   2-289
jupyterlab_server/process_app.py                     30     30     0%   2-53
jupyterlab_server/pytest_plugin.py                   59     17    71%   1-13, 25-26, 91, 106, 120, 132, 138-139
jupyterlab_server/server.py                           5      5     0%   1-9
jupyterlab_server/settings_handler.py               214     56    74%   5-24, 50, 56-58, 65-67, 74, 96-97, 104-106, 117, 131, 145-146, 164, 196, 202, 218, 227, 232, 248-249, 254-255, 260, 268-269, 278, 331-333, 342-346, 359, 363-364, 374, 381, 390-391
jupyterlab_server/tests/test_translation_api.py     126      1    99%   58
jupyterlab_server/tests/utils.py                     46     39    15%   1-20, 24-41, 45-49, 55, 57-59, 62-73
jupyterlab_server/themes_handler.py                  42     42     0%   6-86
jupyterlab_server/translation_utils.py              157     18    89%   49-50, 78-79, 98-101, 130-131, 261-262, 275-276, 318, 334, 371-372, 384
jupyterlab_server/translations_handler.py            35     19    46%   4-23, 49, 54-56, 59-61, 83-84
jupyterlab_server/workspaces_handler.py             118     39    67%   5-21, 28, 43-44, 49, 64, 97-99, 103, 106, 110-111, 115, 121, 127-131, 145-146, 154-155, 162-165, 174-175
-------------------------------------------------------------------------------
TOTAL                                              1575    647    59%

4 files skipped due to complete coverage.


====================================================================== 38 passed in 8.64s ======================================================================

Why am I still posting this issue then? Well, I guess it can help documenting the process for others and missing documentation is probably worth an issue.

Suppress logs of overrides settings

Problem

#224 added log outputs of overrides settings by using print().
These logs are informative but slightly noisy because _get_overrides() is called multiple times for each connection.

with open(overrides_path, encoding="utf-8") as fid:
try:
if overrides_path.endswith(".json5"):
path_overrides = json5.load(fid)
else:
path_overrides = json.load(fid)
for plugin_id, config in path_overrides.items():
recursive_update(overrides.setdefault(plugin_id, {}), config)
print(overrides_path, overrides)

Proposed Solution

  • Remove the print()
  • Replace it with a logging function to be able to select whether to output logs

Additional context

Example logs are as follows:

[C 2022-04-02 23:40:09.458 ServerApp] 
    
    To access the server, open this file in a browser:
        file:///home/jovyan/.local/share/jupyter/runtime/jpserver-7-open.html
    Or copy and paste one of these URLs:
        http://932e71158dae:8888/lab?token=b21128ac8a81fe37e5a8125bc520d7d5fd07df12ca6949a2
     or http://127.0.0.1:8888/lab?token=b21128ac8a81fe37e5a8125bc520d7d5fd07df12ca6949a2
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}
[I 2022-04-02 23:40:26.410 LabApp] Build is up to date
/opt/conda/share/jupyter/lab/settings/overrides.json {'@jupyterlab/apputils-extension:themes': {'theme': 'JupyterLab Dark'}}

I used jupyter/scipy-notebook:lab-3.3.2, which includes jupyterlab-server==2.12.0.
-> detail

Re-raise startup errors or shown them on 404 page?

I was helping a user who had a startup error due to conda/pip conflict (#146 (comment)) and it struck me that they did not really post their tracback in the question, but instead titled it "404 : Not Found You are requesting a page that does not exist!". It kind of makes sense - they did see the 404 page and it was screaming louder than the traceback (which itself was already scrolled up as new messages appeared in the meantime - especially common when multiple jupyter_server extensions are installed!).

Would it be helpful if server re-raised critical startup errors from jupyterlab_server? Getting 404 page might confuse some users, as 404 page becomes the "large screaming message" rather than the traceback that is more useful. Or, possibly even better could the traceback be shown on the 404 page?

From the UX standpoint it seems important to have something more than 404 because users facing different issues all arrive to the same SO question and are annoyed that none of the proposed solutions (many of which actually target different issues that existed in the past) work for them (or maybe one, new solution does).

Request for additions to README about the role of this project within the JupyterLab ecosystem

Thanks for your work on this project!!! โค๏ธ ๐ŸŽ‰

I'm arriving here from a JupyterLab RTC meeting where I learned that this extension to jupyter-server provides some REST API endpoints about settings and workspaces, but that the jupyterlab package registers the /lab path handler.

It would be great to have some additions to the README that clarifies how this project fits in the jupyterlab ecosystem a bit better from the perspective of a learner trying to orient in the ecosystem without so much knowledge about it.

Default branch renamed to main

If you have a local clone, you can update it by running the following commands.

git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a

Hanging string

@telamonian Should this be wrapped in self.log.warn? Is it needed to handle the error here even with the handling of the error within get_current_locale?

try:
locale = self.get_current_locale()
except web.HTTPError as e:
# fallback in case of missing (404) or misshapen (500) translation schema
locale = DEFAULT_LOCALE
'Failed loading or validating translation settings schema'

Originally posted by @fcollonval in #207 (comment)

Adopt a distribution-friendly conf.d-style settings defaults configuration

Problem

Given:

  • extension @a/a distributed as distributed as part of jupyterlab-example-a
  • extension @b/ab, distributed as jupyterlab-example-ab.

@a/a specifies some schema settings, e.g. @a/a:plugin#/some-obj/some-key and can provide sensible defaults in $PREFIX/share/jupyter/labextensions/@a/a/schema/plugin.json.

@b/ab wants to fill in that default, and have it work transparently at startup, but presently cannot without resorting to:

  • tricky Advanced Settings copy-pasta
  • use of user APIs to update the user's settings in-place (e.g. in ~/.jupyter/lab/settings
  • nasty install-time updates of singleton overrides.json or default_settings_overrides.json files

Some areas where this is becoming relevant:

  • an "core" extension is highly extensible by un-coordinated downstreams
    • jupyter-lsp/jupyterlab-lsp#716 (comment)
      • in this case, in order to be fully-installed, a labextension needs to do some manual steps
      • jupyter-lsp could offer some of this itself, but the current model keeps client configuration on the frontend, as it is more subjective
  • an installable course might offer
  • adopting a similar pattern, downstream applications (e.g. retrolab, jupyterlite) could extend this further
    • consult the lab stack
    • use a similar approach for their own spot in share
      • might need to disable certain features

Proposed Solution

Before taking into account the user- or deployer-owned overrides.json, also honor a conf.d-style well-known directory that can be populated by well-named json files.

Concretely, ordering of the construction of the composite (with defaults) would be:

  • the original defaults
    • $PREFIX/share/jupyter/labextensions/@a/b/schema/plugin.json
  • ๐Ÿ†• a TBD sorting of
    • ...
    • $PREFIX/share/jupyter/lab/static/settings/overrides.d/a-a.json
    • ...
    • $PREFIX/share/jupyter/lab/static/settings/overrides.d/a-a-ab.json
    • ...
  • a deploy-time configured default paths
    • $PREFIX/share/jupyter/lab/static/settings/overrides.json5
  • a user's default_settings_overrides.json in their Jupyter config paths
    • ...
    • ~/.jupyter/labconfig/default_setting_overrides.json
    • ...
    • $PREFIX/etc/jupyter/labconfig/default_setting_overrides.json
    • ...
  • the user's configuration
    • ~/.jupyter/lab/user-settings/@a/a/plugin.jupyterlab-settings

TBD: the ideal would be topological, but perhaps just reversed name is easiest to reason about

As usual, extension authors would use their chosen technique for populating overrides.d via data_files.

here's a strawman implementation:

diff --git a/jupyterlab_server/settings_utils.py b/jupyterlab_server/settings_utils.py
index bcd914d..b15cd46 100755
--- a/jupyterlab_server/settings_utils.py
+++ b/jupyterlab_server/settings_utils.py
@@ -266,19 +266,40 @@ def _path(root_dir, schema_name, make_dirs=False, extension='.json'):
 
     return path
 
-
 def _get_overrides(app_settings_dir):
-    """Get overrides settings from `app_settings_dir`."""
+    """Get overrides settings from `app_settings_dir`.
+
+    The ordering of paths is:
+    - {app_settings_dir}/overrides.d/*.{json,json5}
+    - {app_settings_dir}/overrides.{json,json5}
+
+    """
     overrides, error = {}, ""
-    overrides_path = os.path.join(app_settings_dir, 'overrides.json')
 
-    if not os.path.exists(overrides_path):
-        overrides_path = os.path.join(app_settings_dir, 'overrides.json5')
+    overrides_d = os.path.join(app_settings_dir, 'overrides.d')
+
+    # find (and sort) the conf.d overrides files
+    all_override_paths = sorted(
+        *(glob(os.path.join(overrides_d, '*.json'))),
+        *(glob(os.path.join(overrides_d, '*.json5'))),
+    )
+
+    all_override_paths += [
+        os.path.join(app_settings_dir, 'overrides.json'),
+        os.path.join(app_settings_dir, 'overrides.json5')
+    ]
+
+    for overrides_path in all_override_paths:
+        if not os.path.exists(overrides_path):
+            continue
 
-    if os.path.exists(overrides_path):
         with open(overrides_path, encoding='utf-8') as fid:
             try:
-                overrides = json5.load(fid)
+                if overrides_path.endswith('.json5'):
+                    path_overrides = json5.load(fid)
+                else:
+                    path_overrides = json.load(fid)
+                recursive_update(overrides, path_overrides)
             except Exception as e:
                 error = e

Additional context

The "conf.d approach" has been useful in a number of settings across the jupyter ecosystem:

The benefits are often shown by gains for packaging approaches that don't allow (or otherwise strongly-discourage) install-time code.

Do not send parsed JSON5 setting data as JSON

Description

The server produces invalid json for a settings get request if the raw setting text includes a value allowed by JSON5, but not by JSON (such as Infinity)

Reproduce

Add a user-level setting, such as Notebook.numberCellsToRenderDirectly, and set it to Infinity. This is a value that is allowed by JSON5, but is not allowed by JSON. Then start JupyterLab and note the many errors in the console about not being able to parse the results of the settings request.

Basically, this line adds converts the JSON5 raw setting to JSON:

settings = json5.loads(raw)

It does a pretty good job of stripping comments, etc, but it leaves in the Infinity. Python can serialize Infinity just fine, but the browser chokes on the response, giving an error like JSON.parse: unexpected character at line 1 column 25047 of the JSON data

Since we've standardized on JSON5, I think perhaps we should not try to include a parsed version of the setting. Instead, just send the raw text over and do a json5 conversion in the browser.

Expected behavior

Infinity to be properly recognized by the setting system.

Context

  • Operating System and version: macOS Catalina
  • Browser and version: Firefox 92
  • JupyterLab version: 3.2 unreleased master

Add Language Server Protocol handler to JupyterLab

Problem

For now, LSP support for JupyterLab is provided by jupyterlab-lsp extension. While this monorepo offers a complete package with a lot of features, it's not easy for JupyterLab core or external extensions to profit from the LSP features.

Proposed Solution

I'm thinking about adding the handlers which allow JupyterLab frontend to communicate with the language server in the backend. It can be done by upstreaming the jupyter_lsp package of jupyterlab-lsp.

The second step is to create a frontend extension in JupyterLab core that can be served as an entry point for other extensions to request the LSP features.

gettext not have dpgettext attribute when using python3.7

Description

when using lower version of python, a error may be raised beacause python libraries is not compatiable with jupyterlab_server.

for example, when use gettext for translation, the dpgettext is add after python 3.7.

should there be some warning for use or do some code change for compatibility?

Tests incomplete in sdist

I got errors like this when I try to run the tests from sdist tarball from PyPI.

E           requests.exceptions.HTTPError: 404 Client Error: Schema not found: '/builddir/build/BUILD/jupyterlab_launcher-0.10.4/jupyterlab_launcher/tests/schemas/@jupyterlab/apputils-extension/themes.json' for url: http://localhost:12341/a%40b/lab/api/settings/@jupyterlab/apputils-extension:themes

I suppose it's because jupyterlab_launcher/tests/workspaces/ and jupyterlab_launcher/tests/schemas/@jupyterlab/ are not in the tarball.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.