worked out some bugs

This commit is contained in:
Brennen Raimer
2024-05-13 14:49:21 -04:00
parent 6b7099a933
commit c27f5f73f4
2 changed files with 90 additions and 42 deletions

View File

@@ -1,9 +1,76 @@
import logging
import platform
from io import StringIO
from itertools import product
from os import environ
from pathlib import Path
from subprocess import CalledProcessError, run
logging.getLogger(__name__).propagate=True
def find_flatpak_browser():
if platform.system() != "Linux":
return
for path_element in map(Path, environ["PATH"].split(":")):
if (path_element/"flatpak").is_file():
flatpak_bin = path_element/"flatpak"
break
else:
# flatpak is not installed
return
flatpak_apps = ("com.google.Chrome", "com.microsoft.Edge", "com.brave.Browser", "org.chromium.Chromium")
try:
flatpak_process = run(
[
str(flatpak_bin),
"list",
"--app",
"--columns=application"
],
capture_output=True,
check=True
)
except CalledProcessError as e:
pass
else:
with StringIO(flatpak_process.stdout.decode()) as flatpak_output:
installed_flatpaks = flatpak_output.readlines()[1:]
for flatpak_app in flatpak_apps:
if flatpak_app in [_.strip() for _ in installed_flatpaks]:
return f"flatpak run --filesystem={Path.home()/'.local/share/jupyter/runtime'} {flatpak_app} --start-maximized --profile-directory=Default --app=%s"
def find_browser():
# find a chromium-based browser on the system to use.
if platform.system() == "Windows":
# prefers Microsoft Edge on Windows
cmds = (
"Microsoft/Edge/Application/msedge.exe",
"Google/Chrome/Application/chrome.exe",
)
path_elements = map(Path, (environ["ProgramFiles"], environ["ProgramFiles(x86)"]))
elif platform.system() == "Linux":
# prefers Google Chrome on Linux due to popularity of the browser
cmds = ("google-chrome", "microsoft-edge", "brave", "chromium")
path_elements = map(Path, environ["PATH"].split(":"))
elif platform.system() == "Darwin":
# also prefers Google Chrome on MacOS due to popularity of the browser
cmds = ("Contents/MacOS/Google Chrome", "Contents/MacOS/Microsoft Edge")
path_elements = [Path(f"/Applications/{Path(cmd).name}.app") for cmd in cmds]
# use the first chromium-based browser found as the browser to run Jupyter in app mode
for cmd, path_element in product(cmds, path_elements):
browser = path_element / cmd
if browser.exists():
return f'"{browser}" --start-maximized --profile-directory=Default --app=%s'
# generated if you run `jupyter lab --generate-config`, used for additional configuration
DEFAULT_CONFIG_FILE = Path.home() / ".jupyter/jupyter_lab_config.py"
@@ -11,33 +78,10 @@ DEFAULT_CONFIG_FILE = Path.home() / ".jupyter/jupyter_lab_config.py"
# user's home will be the root path of jupyter's file explorer
c.ServerApp.root_dir = str(Path.home())
# find a chromium-based browser on the system to use.
if platform.system() == "Windows":
# prefers Microsoft Edge on Windows
cmds = (
"Microsoft/Edge/Application/msedge.exe",
"Google/Chrome/Application/chrome.exe",
)
path_elements = map(Path, (environ["ProgramFiles"], environ["ProgramFiles(x86)"]))
browser_cmd = find_flatpak_browser() or find_browser()
elif platform.system() == "Linux":
# prefers Google Chrome on Linux due to popularity of the browser
cmds = ("google-chrome", "microsoft-edge", "brave", "chromium")
path_elements = map(Path, environ["PATH"].split(":"))
elif platform.system() == "Darwin":
# also prefers Google Chrome on MacOS due to popularity of the browser
cmds = ("Contents/MacOS/Google Chrome", "Contents/MacOS/Microsoft Edge")
path_elements = [Path(f"/Applications/{Path(cmd).name}.app") for cmd in cmds]
# use the first chromium-based browser found as the browser to run Jupyter in app mode
for cmd, path_element in product(cmds, path_elements):
browser = path_element / cmd
if browser.exists():
c.ServerApp.browser = (
f'"{browser}" --start-maximized --profile-directory=Default --app=%s'
)
break
if browser_cmd:
c.ServerApp.browser = browser_cmd
else:
logging.getLogger(__name__).warning(
"No Chromium-based browser was found on this system, therefore Jupyter will run "

36
setup_jupyter.py Normal file → Executable file
View File

@@ -4,8 +4,7 @@ import platform
from argparse import ArgumentParser
from json import JSONDecodeError, loads
from os import environ, linesep
from os.path import Pathlike
from os import PathLike, environ, linesep
from pathlib import Path
from shutil import copy
from subprocess import CalledProcessError, run
@@ -53,7 +52,7 @@ def get_base_prefix() -> Path:
def get_menuinst_version() -> tuple[str, str, str]:
conda_process = run(["conda", "list", "--prefix", str(get_base_prefix()), "--json"], check=True)
conda_process = run(["conda", "list", "--prefix", str(get_base_prefix()), "--json"], capture_output=True, check=True)
try:
conda_pkgs = loads(conda_process.stdout)
@@ -87,7 +86,7 @@ def meets_prerequisites() -> bool:
def stage_configs(destination_dir: Path) -> Path:
repo_dir = Path(__file__).parent
shortcut_json = repo_dir / "jupyterlab_extension.json"
shortcut_json = repo_dir / "jupyterlab_shortcut.json"
jupyterlab_config = repo_dir / "jupyter_lab_config.py"
LOGGER.debug(f"Repository directory is {repo_dir}")
@@ -106,7 +105,7 @@ def stage_configs(destination_dir: Path) -> Path:
return shortcut_json
def download_icon_file(menu_dir: Pathlike):
def download_icon_file(menu_dir: PathLike):
LOGGER.debug(f"OS is {platform.system()}")
match platform.system():
case "Windows":
@@ -125,7 +124,7 @@ def download_icon_file(menu_dir: Pathlike):
raise RuntimeError("Unable to download an icon to use for the JupyterLab shortcut") from e
else:
file_extension = Path(urlparse(url).path).suffix
with (Path(menu_dir) / f"jupyterlab.{file_extension}").open("wb") as icon_file:
with (Path(menu_dir) / f"jupyterlab{file_extension}").open("wb") as icon_file:
LOGGER.debug(f"Writing icon file to {icon_file.name}")
icon_file.write(response.content)
@@ -133,7 +132,7 @@ def download_icon_file(menu_dir: Pathlike):
svg_to_icns(menu_dir/"jupyterlab.svg")
def svg_to_icns(svg_file: Pathlike) -> None:
def svg_to_icns(svg_file: PathLike) -> None:
if not platform.system() == "Darwin":
raise RuntimeError("svg_to_icns is designed to run on MacOS only")
@@ -208,7 +207,7 @@ def ensure_env(env_name: str) -> Path:
"--name",
env_name
],
capture=True,
capture_output=True,
check=False
)
@@ -219,7 +218,7 @@ def ensure_env(env_name: str) -> Path:
else:
env_prefix = get_base_prefix()/f"envs/{env_name}"
if "error" in env_spec.keys():
if isinstance(env_spec, dict) and "error" in env_spec.keys():
# enviornment doesn't exist. create one with some commonly used packages
# including ipywidgets because it will automatically install the plugin to render them in jupyterlab
# ultimately, though, nb_conda_kernels allows the execution of notebooks in any installed conda environment
@@ -314,7 +313,7 @@ def main(target_env_name: str) -> int:
LOGGER.warning("Not in base environment. Re-running this script from the base environment")
# call conda run to re-run this in the base prefix
rerun_proces = run(
["conda", "run", "--prefix", str(get_base_prefix()), "--no-capture-output", "python", __file__, *argv[1:]],
["conda", "run", "--prefix", str(get_base_prefix()), "--no-capture-output", "python", *argv],
capture_output=False,
check=False
)
@@ -328,7 +327,7 @@ def main(target_env_name: str) -> int:
check=True
)
run(["python", __file__, *argv[1:]], capture_output=False, check=True)
run(["python", *argv], capture_output=False, check=True)
elif meets_prerequisites():
from menuinst.api import install, remove
@@ -367,21 +366,26 @@ if __name__ == "__main__":
DEBUG_HANDLER = logging.StreamHandler(stderr)
DEBUG_HANDLER.setLevel(logging.DEBUG)
DEBUG_HANDLER.addFilter(lambda r: r.levelno < logging.INFO)
DEBUG_HANDLER.setFormatter()
DEBUG_HANDLER.setFormatter(
logging.Formatter(
"{levelname}: {message}",
style="{"
)
)
parser = ArgumentParser()
parser.add_argument(
"--debug",
action = "store_true",
description = "Enable debug logging to the terminal"
help = "Enable debug logging to the terminal"
)
parser.add_argument(
"name",
default="jupyter",
description = "Name of the target conda environment containing JupyterLab. If it does not exist, one will be created"
help = "Name of the target conda environment containing JupyterLab. If it does not exist, one will be created"
)
args = parser.parse_args(argv)
args = parser.parse_args()
if args.debug:
logging.basicConfig(