Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade fro JupyterLab 4 #209

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Lin the code
  • Loading branch information
fcollonval committed Nov 26, 2023
commit 1ac844dcde220aa062fe37d7e15819a70d8755d2
4 changes: 2 additions & 2 deletions binder/jupyter_server_config.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import sys

c.ServerProxy.servers = {
c.ServerProxy.servers = { # noqa F821
"mamba": {
"command": [
sys.executable,
"-m",
"mamba_gator",
"--no-browser",
'--port={port}',
"--port={port}",
"--ip=0.0.0.0",
"--ServerApp.token=''",
"--ServerApp.base_url={base_url}mamba",
Expand Down
5 changes: 4 additions & 1 deletion mamba_gator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ def _jupyter_labextension_paths():


def _jupyter_server_extension_points():
return [{"module": "mamba_gator"}, {"module": "mamba_gator.navigator.main", "app": MambaNavigator}]
return [
{"module": "mamba_gator"},
{"module": "mamba_gator.navigator.main", "app": MambaNavigator},
]


# For backward compatibility
Expand Down
68 changes: 20 additions & 48 deletions mamba_gator/envmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,7 @@ async def _execute(self, cmd: str, *args) -> Tuple[int, str]:
None, partial(Popen, cmdline, stdout=PIPE, stderr=PIPE)
)
try:
output, error = await current_loop.run_in_executor(
None, process.communicate
)
output, error = await current_loop.run_in_executor(None, process.communicate)
except asyncio.CancelledError:
process.terminate()
await current_loop.run_in_executor(None, process.wait)
Expand Down Expand Up @@ -196,9 +194,7 @@ def manager(self) -> str:
if sys.platform == "win32":
cmd = ["where", "mamba.exe"]

process = Popen(
cmd, stdout=PIPE, stderr=PIPE, encoding="utf-8"
)
process = Popen(cmd, stdout=PIPE, stderr=PIPE, encoding="utf-8")
output, error = process.communicate()

if process.returncode != 0:
Expand All @@ -217,7 +213,7 @@ def manager(self) -> str:
if process.returncode != 0:
raise RuntimeError(error)

versions = list(map(lambda l: l.split(), output.splitlines()))
versions = list(map(lambda line: line.split(), output.splitlines()))
if versions[0][0] == "mamba" and versions[1][0] == "conda":
EnvManager._conda_version = versions[1][1]
EnvManager._mamba_version = versions[0][1]
Expand Down Expand Up @@ -269,9 +265,7 @@ def get_uri(spec):
get_uri(entry) for entry in info["custom_multichannels"][channel]
]
elif strip_channel in info["custom_channels"]:
deployed_channels[strip_channel] = [
get_uri(info["custom_channels"][strip_channel])
]
deployed_channels[strip_channel] = [get_uri(info["custom_channels"][strip_channel])]
else:
parsed_channel = tornado.httputil.urlparse(channel)
if parsed_channel.scheme:
Expand Down Expand Up @@ -327,9 +321,7 @@ async def create_env(self, env: str, *args) -> Dict[str, str]:
Returns:
Dict[str, str]: Create command output
"""
ans = await self._execute(
self.manager, "create", "-y", "-q", "--json", "-n", env, *args
)
ans = await self._execute(self.manager, "create", "-y", "-q", "--json", "-n", env, *args)

rcode, output = ans
if rcode > 0:
Expand All @@ -345,18 +337,14 @@ async def delete_env(self, env: str) -> Dict[str, str]:
Returns:
Dict[str, str]: Deletion command output
"""
ans = await self._execute(
self.manager, "env", "remove", "-y", "-q", "--json", "-n", env
)
ans = await self._execute(self.manager, "env", "remove", "-y", "-q", "--json", "-n", env)

rcode, output = ans
if rcode > 0:
return {"error": output}
return output

async def export_env(
self, env: str, from_history: bool = False
) -> Union[str, Dict[str, str]]:
async def export_env(self, env: str, from_history: bool = False) -> Union[str, Dict[str, str]]:
"""Export an environment as YAML file.

Args:
Expand Down Expand Up @@ -558,9 +546,7 @@ async def pkg_depends(self, pkg: str) -> Dict[str, List[str]]:
"""
if not self.is_mamba():
self.log.warning(
"Package manager '{}' does not support dependency query.".format(
self.manager
)
"Package manager '{}' does not support dependency query.".format(self.manager)
)
return {pkg: None}

Expand All @@ -571,7 +557,7 @@ async def pkg_depends(self, pkg: str) -> Dict[str, List[str]]:

if "error" not in query:
for dep in query["result"]["pkgs"]:
if type(dep) is dict:
if isinstance(dep, dict):
deps = dep.get("depends", None)
if deps:
resp[dep["name"]] = deps
Expand Down Expand Up @@ -609,9 +595,9 @@ def process_mamba_repoquery_output(data: Dict) -> Dict:
of "conda search --json".
"""

data_ = collections.defaultdict(lambda : [])
for entry in data['result']['pkgs']:
name = entry.get('name')
data_ = collections.defaultdict(lambda: [])
for entry in data["result"]["pkgs"]:
name = entry.get("name")
if name is not None:
data_[name].append(entry)

Expand Down Expand Up @@ -660,7 +646,7 @@ def format_packages(data: Dict) -> List:
pkg_entry = entry

try:
version = parse(entry.get("version", ""))
version = parse(entry.get("version", ""))
except InvalidVersion:
name = entry.get("name")
version = entry.get("version")
Expand All @@ -676,21 +662,13 @@ def format_packages(data: Dict) -> List:
build_number = entry.get("build_number", 0)
if build_number > max_build_numbers[version_idx]:
max_build_numbers[version_idx] = build_number
max_build_strings[version_idx] = entry.get(
"build_string", ""
)
max_build_strings[version_idx] = entry.get("build_string", "")

sorted_versions_idx = sorted(
range(len(versions)), key=versions.__getitem__
)
sorted_versions_idx = sorted(range(len(versions)), key=versions.__getitem__)

pkg_entry["version"] = [str(versions[i]) for i in sorted_versions_idx]
pkg_entry["build_number"] = [
max_build_numbers[i] for i in sorted_versions_idx
]
pkg_entry["build_string"] = [
max_build_strings[i] for i in sorted_versions_idx
]
pkg_entry["build_number"] = [max_build_numbers[i] for i in sorted_versions_idx]
pkg_entry["build_string"] = [max_build_strings[i] for i in sorted_versions_idx]

packages.append(pkg_entry)
return packages
Expand Down Expand Up @@ -848,9 +826,7 @@ async def package_search(self, q: str) -> Dict[str, List]:
"with_description": False,
}

async def check_update(
self, env: str, packages: List[str]
) -> Dict[str, List[Dict[str, str]]]:
async def check_update(self, env: str, packages: List[str]) -> Dict[str, List[Dict[str, str]]]:
"""Check for packages update in an environment.

if '--all' is the only element in `packages`, search for all
Expand Down Expand Up @@ -890,9 +866,7 @@ async def check_update(
links = data["actions"].get("LINK", [])
package_versions = [link for link in links]
return {
"updates": [
normalize_pkg_info(pkg_version) for pkg_version in package_versions
]
"updates": [normalize_pkg_info(pkg_version) for pkg_version in package_versions]
}
else:
# no action plan returned means everything is already up to date
Expand Down Expand Up @@ -947,9 +921,7 @@ async def develop_packages(
realpath = os.path.realpath(os.path.expanduser(path))
if not os.path.exists(realpath):
# Convert jupyterlab path to local path if the path does not exists
realpath = os.path.realpath(
os.path.join(self._root_dir, url2path(path))
)
realpath = os.path.realpath(os.path.join(self._root_dir, url2path(path)))
if not os.path.exists(realpath):
return {"error": "Unable to find path {}.".format(path)}

Expand Down
19 changes: 4 additions & 15 deletions mamba_gator/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
# pylint: disable=W0221

import asyncio
import collections
import json
import logging
import os
import re
import stat
import sys
import tempfile
Expand Down Expand Up @@ -205,9 +203,7 @@ def post(self):
elif twin is not None:
idx = self._stack.put(self.env_manager.clone_env, twin, name)
elif file_content is not None:
idx = self._stack.put(
self.env_manager.import_env, name, file_content, file_name
)
idx = self._stack.put(self.env_manager.import_env, name, file_content, file_name)
else:
idx = self._stack.put(self.env_manager.create_env, name)

Expand Down Expand Up @@ -239,9 +235,7 @@ async def get(self, env: str):

if download:
# export requirements file
self.set_header(
"Content-Disposition", 'attachment; filename="%s"' % (env + ".yml")
)
self.set_header("Content-Disposition", 'attachment; filename="%s"' % (env + ".yml"))
answer = await self.env_manager.export_env(env, bool(history))
if "error" in answer:
self.set_status(500)
Expand Down Expand Up @@ -403,9 +397,7 @@ async def update_available(
# Request cache update in background
if not PackagesHandler.__is_listing_available:
PackagesHandler.__is_listing_available = True
self._stack.put(
update_available, self.env_manager, cache_file, False
)
self._stack.put(update_available, self.env_manager, cache_file, False)
# Return current cache
self.set_status(200)
self.finish(cache_data)
Expand Down Expand Up @@ -505,10 +497,7 @@ def _load_jupyter_server_extension(server_app):
base_url = webapp.settings["base_url"]
webapp.add_handlers(
".*$",
[
(url_path_join(base_url, NS, pat), handler)
for pat, handler in default_handlers
],
[(url_path_join(base_url, NS, pat), handler) for pat, handler in default_handlers],
)

get_logger().info("Server extension enabled")
6 changes: 1 addition & 5 deletions mamba_gator/navigator/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import logging
import os

from jupyter_server.base.handlers import JupyterHandler
Expand All @@ -12,14 +11,11 @@
from jupyterlab_server import LabServerApp
from mamba_gator._version import __version__
from mamba_gator.handlers import _load_jupyter_server_extension
from mamba_gator.log import get_logger

HERE = os.path.dirname(__file__)


class MambaNavigatorHandler(
ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler
):
class MambaNavigatorHandler(ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler):
def get(self):
config_data = {
"appVersion": __version__,
Expand Down
3 changes: 1 addition & 2 deletions mamba_gator/tests/test_actionsstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import functools
import subprocess
import sys
import time

import pytest
from mamba_gator.handlers import ActionsStack
Expand Down Expand Up @@ -113,7 +112,7 @@ async def f(i):
idxs.append(a.put(f, b))

len(idxs) == len(to_be_tested)
for l in idxs:
for l in idxs: # noqa E741
assert isinstance(l, int)
assert a.get(l) is None

Expand Down
Loading