mbuali's picture
Upload folder using huggingface_hub
d1ceb73 verified
"""Tornado handlers for extension management."""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import dataclasses
import json
from urllib.parse import urlencode, urlunparse
from jupyter_server.base.handlers import APIHandler
from tornado import web
from jupyterlab.extensions.manager import ExtensionManager
class ExtensionHandler(APIHandler):
def initialize(self, manager: ExtensionManager):
super().initialize()
self.manager = manager
@web.authenticated
async def get(self):
"""GET query returns info on extensions
Query arguments:
refresh: [optional] Force refreshing the list of extensions - ["0", "1"]; default 0
query: [optional] Query to search for extensions - default None (i.e. returns installed extensions)
page: [optional] Result page - default 1 (min. 1)
per_page: [optional] Number of results per page - default 30 (max. 100)
"""
query = self.get_argument("query", None)
page = max(1, int(self.get_argument("page", "1")))
per_page = min(100, int(self.get_argument("per_page", "30")))
if self.get_argument("refresh", "0") == "1":
await self.manager.refresh(query, page, per_page)
extensions, last_page = await self.manager.list_extensions(query, page, per_page)
self.set_status(200)
if last_page is not None:
links = []
query_args = {"page": last_page, "per_page": per_page}
if query is not None:
query_args["query"] = query
last = urlunparse(
(
self.request.protocol,
self.request.host,
self.request.path,
"",
urlencode(query_args, doseq=True),
"",
)
)
links.append(f'<{last}>; rel="last"')
if page > 1:
query_args["page"] = max(1, page - 1)
prev = urlunparse(
(
self.request.protocol,
self.request.host,
self.request.path,
"",
urlencode(query_args, doseq=True),
"",
)
)
links.append(f'<{prev}>; rel="prev"')
if page < last_page:
query_args["page"] = min(page + 1, last_page)
next_ = urlunparse(
(
self.request.protocol,
self.request.host,
self.request.path,
"",
urlencode(query_args, doseq=True),
"",
)
)
links.append(f'<{next_}>; rel="next"')
query_args["page"] = 1
first = urlunparse(
(
self.request.protocol,
self.request.host,
self.request.path,
"",
urlencode(query_args, doseq=True),
"",
)
)
links.append(f'<{first}>; rel="first"')
self.set_header("Link", ", ".join(links))
self.finish(json.dumps(list(map(dataclasses.asdict, extensions))))
@web.authenticated
async def post(self):
"""POST query performs an action on a specific extension
Body arguments:
{
"cmd": Action to perform - ["install", "uninstall", "enable", "disable"]
"extension_name": Extension name
"extension_version": [optional] Extension version (used only for install action)
}
"""
data = self.get_json_body()
cmd = data["cmd"]
name = data["extension_name"]
version = data.get("extension_version")
if cmd not in ("install", "uninstall", "enable", "disable") or not name:
raise web.HTTPError(
422,
f"Could not process instruction {cmd!r} with extension name {name!r}",
)
ret_value = None
try:
if cmd == "install":
ret_value = await self.manager.install(name, version)
elif cmd == "uninstall":
ret_value = await self.manager.uninstall(name)
elif cmd == "enable":
ret_value = await self.manager.enable(name)
elif cmd == "disable":
ret_value = await self.manager.disable(name)
except Exception as e:
raise web.HTTPError(500, str(e)) from e
if ret_value.status == "error":
self.set_status(500)
else:
self.set_status(201)
self.finish(json.dumps(dataclasses.asdict(ret_value)))
# The path for lab extensions handler.
extensions_handler_path = r"/lab/api/extensions"