diff --git a/docs/source/api/handlers.rst b/docs/source/api/handlers.rst index f3e13d02..f002f76c 100644 --- a/docs/source/api/handlers.rst +++ b/docs/source/api/handlers.rst @@ -17,19 +17,6 @@ Module: :mod:`jupyterlab_server.handlers` .. autofunction:: is_url -Module: :mod:`jupyterlab_server.listings_handler` -================================================= - -.. automodule:: jupyterlab_server.listings_handler - -.. currentmodule:: jupyterlab_server.listings_handler - -.. autoclass:: ListingsHandler - :members: - -.. autofunction:: fetch_listings - - Module: :mod:`jupyterlab_server.settings_handler` ================================================= diff --git a/jupyterlab_server/app.py b/jupyterlab_server/app.py index 69f67c78..bd4ce545 100644 --- a/jupyterlab_server/app.py +++ b/jupyterlab_server/app.py @@ -29,33 +29,19 @@ def app_namespace(self): app_version = Unicode("", help="The version of the application.").tag(default=__version__) - blacklist_uris = Unicode( - "", config=True, help="Deprecated, use `LabServerApp.blocked_extensions_uris`" - ) - blocked_extensions_uris = Unicode( "", config=True, help=""" A list of comma-separated URIs to get the blocked extensions list - - .. versionchanged:: 2.0.0 - `LabServerApp.blacklist_uris` renamed to `blocked_extensions_uris` """, ) - whitelist_uris = Unicode( - "", config=True, help="Deprecated, use `LabServerApp.allowed_extensions_uris`" - ) - allowed_extensions_uris = Unicode( "", config=True, help=""" - "A list of comma-separated URIs to get the allowed extensions list - - .. versionchanged:: 2.0.0 - `LabServerApp.whitetlist_uris` renamed to `allowed_extensions_uris` + A list of comma-separated URIs to get the allowed extensions list """, ) @@ -63,40 +49,13 @@ def app_namespace(self): 60 * 60, config=True, help="The interval delay in seconds to refresh the lists" ) - listings_request_options = Dict( + listings_tornado_options = Dict( {}, config=True, help="The optional kwargs to use for the listings HTTP requests \ - as described on https://2.python-requests.org/en/v2.7.0/api/#requests.request", + as described on https://www.tornadoweb.org/en/stable/httpclient.html#tornado.httpclient.HTTPRequest", ) - _deprecated_aliases = { - "blacklist_uris": ("blocked_extensions_uris", "1.2"), - "whitelist_uris": ("allowed_extensions_uris", "1.2"), - } - - # Method copied from - # https://github.com/jupyterhub/jupyterhub/blob/d1a85e53dccfc7b1dd81b0c1985d158cc6b61820/jupyterhub/auth.py#L143-L161 - @observe(*list(_deprecated_aliases)) - def _deprecated_trait(self, change): - """observer for deprecated traits""" - old_attr = change.name - new_attr, version = self._deprecated_aliases.get(old_attr) - new_value = getattr(self, new_attr) - if new_value != change.new: - # only warn if different - # protects backward-compatible config from warnings - # if they set the same value under both names - self.log.warning( - "{cls}.{old} is deprecated in JupyterLab {version}, use {cls}.{new} instead".format( - cls=self.__class__.__name__, - old=old_attr, - new=new_attr, - version=version, - ) - ) - setattr(self, new_attr, change.new) - def initialize_templates(self): self.static_paths = [self.static_dir] self.template_paths = [self.templates_dir] diff --git a/jupyterlab_server/handlers.py b/jupyterlab_server/handlers.py index f9eea346..35f03b4b 100644 --- a/jupyterlab_server/handlers.py +++ b/jupyterlab_server/handlers.py @@ -15,7 +15,6 @@ from .config import LabConfig, get_page_config, recursive_update from .licenses_handler import LicensesHandler, LicensesManager -from .listings_handler import ListingsHandler, fetch_listings from .server import FileFindHandler, JupyterHandler from .server import url_path_join as ujoin from .settings_handler import SettingsHandler @@ -249,49 +248,6 @@ def add_handlers(handlers, extension_app): workspace_api_path = ujoin(extension_app.workspaces_api_url, "(?P.+)") handlers.append((workspace_api_path, WorkspacesHandler, workspaces_config)) - # Handle local listings. - - settings_config = extension_app.settings.get("config", {}).get("LabServerApp", {}) - blocked_extensions_uris = settings_config.get("blocked_extensions_uris", "") - allowed_extensions_uris = settings_config.get("allowed_extensions_uris", "") - - if (blocked_extensions_uris) and (allowed_extensions_uris): - warnings.warn( - "Simultaneous blocked_extensions_uris and allowed_extensions_uris is not supported. Please define only one of those." - ) - import sys - - sys.exit(-1) - - ListingsHandler.listings_refresh_seconds = settings_config.get( - "listings_refresh_seconds", 60 * 60 - ) - ListingsHandler.listings_request_opts = settings_config.get("listings_request_options", {}) - listings_url = ujoin(extension_app.listings_url) - listings_path = ujoin(listings_url, "(.*)") - - if blocked_extensions_uris: - ListingsHandler.blocked_extensions_uris = set(blocked_extensions_uris.split(",")) - if allowed_extensions_uris: - ListingsHandler.allowed_extensions_uris = set(allowed_extensions_uris.split(",")) - - fetch_listings(None) - - if ( - len(ListingsHandler.blocked_extensions_uris) > 0 - or len(ListingsHandler.allowed_extensions_uris) > 0 - ): - from tornado import ioloop - - ListingsHandler.pc = ioloop.PeriodicCallback( - lambda: fetch_listings(None), - callback_time=ListingsHandler.listings_refresh_seconds * 1000, - jitter=0.1, - ) - ListingsHandler.pc.start() - - handlers.append((listings_path, ListingsHandler, {})) - # Handle local themes. if extension_app.themes_dir: themes_url = extension_app.themes_url diff --git a/jupyterlab_server/listings_handler.py b/jupyterlab_server/listings_handler.py deleted file mode 100644 index 9407192b..00000000 --- a/jupyterlab_server/listings_handler.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Tornado handlers for listing extensions.""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import json - -import requests -import tornado - -from .server import APIHandler - -LISTINGS_URL_SUFFIX = "@jupyterlab/extensionmanager-extension/listings.json" - - -def fetch_listings(logger): - """Fetch the listings for the extension manager.""" - if not logger: - from traitlets import log - - logger = log.get_logger() - if len(ListingsHandler.blocked_extensions_uris) > 0: - blocked_extensions = [] - for blocked_extensions_uri in ListingsHandler.blocked_extensions_uris: - logger.info( - "Fetching blocked_extensions from {}".format( - ListingsHandler.blocked_extensions_uris - ) - ) - r = requests.request( - "GET", blocked_extensions_uri, **ListingsHandler.listings_request_opts - ) - j = json.loads(r.text) - for b in j["blocked_extensions"]: - blocked_extensions.append(b) - ListingsHandler.blocked_extensions = blocked_extensions - if len(ListingsHandler.allowed_extensions_uris) > 0: - allowed_extensions = [] - for allowed_extensions_uri in ListingsHandler.allowed_extensions_uris: - logger.info( - "Fetching allowed_extensions from {}".format( - ListingsHandler.allowed_extensions_uris - ) - ) - r = requests.request( - "GET", allowed_extensions_uri, **ListingsHandler.listings_request_opts - ) - j = json.loads(r.text) - for w in j["allowed_extensions"]: - allowed_extensions.append(w) - ListingsHandler.allowed_extensions = allowed_extensions - ListingsHandler.listings = json.dumps( - { - "blocked_extensions_uris": list(ListingsHandler.blocked_extensions_uris), - "allowed_extensions_uris": list(ListingsHandler.allowed_extensions_uris), - "blocked_extensions": ListingsHandler.blocked_extensions, - "allowed_extensions": ListingsHandler.allowed_extensions, - } - ) - - -class ListingsHandler(APIHandler): - """An handler that returns the listings specs.""" - - """Below fields are class level fields that are accessed and populated - by the initialization and the fetch_listings methods. - Some fields are initialized before the handler creation in the - handlers.py#add_handlers method. - Having those fields predefined reduces the guards in the methods using - them. - """ - # The list of blocked_extensions URIS. - blocked_extensions_uris = set() - # The list of allowed_extensions URIS. - allowed_extensions_uris = set() - # The blocked extensions extensions. - blocked_extensions = [] - # The allowed extensions extensions. - allowed_extensions = [] - # The provider request options to be used for the request library. - listings_request_opts = {} - # The PeriodicCallback that schedule the call to fetch_listings method. - pc = None - - def get(self, path): - """Get the listings for the extension manager.""" - self.set_header("Content-Type", "application/json") - if path == LISTINGS_URL_SUFFIX: - self.write(ListingsHandler.listings) - else: - raise tornado.web.HTTPError(400) diff --git a/jupyterlab_server/rest-api.yml b/jupyterlab_server/rest-api.yml index 4fc0ffe8..5b817736 100644 --- a/jupyterlab_server/rest-api.yml +++ b/jupyterlab_server/rest-api.yml @@ -8,39 +8,6 @@ info: name: BSD-3-Clause paths: - /lab/api/listings/%40jupyterlab/extensionmanager-extension/listings.json: - get: - summary: Get Extension Listings Specs - description: | - Gets the list of extension metadata for the application - responses: - "200": - description: The Extension Listing specs - content: - application/json: - schema: - properties: - blocked_extension_uris: - type: array - description: list of blocked extension uris - items: - type: string - allowed_extension_uris: - type: array - description: list of allowed extension uris - items: - type: string - blocked_extensions: - type: array - description: list of blocked extensions - items: - $ref: "#/components/schemas/ListEntry" - allowed_extensions: - type: array - description: list of blocked extensions - items: - $ref: "#/components/schemas/ListEntry" - /lab/api/settings/: get: summary: Get Settings List diff --git a/tests/test_listings_api.py b/tests/test_listings_api.py deleted file mode 100644 index 8224759a..00000000 --- a/tests/test_listings_api.py +++ /dev/null @@ -1,7 +0,0 @@ -from jupyterlab_server.test_utils import validate_request - - -async def test_get_listing(jp_fetch, labserverapp): - url = r"lab/api/listings/@jupyterlab/extensionmanager-extension/listings.json" - r = await jp_fetch(*url.split("/")) - validate_request(r)