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": cmds = ( "Google/Chrome/Application/chrome.exe", "BraveSoftware/Brave-Browser/Application/brave.exe", "Microsoft/Edge/Application/msedge.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", "Contents/MacOS/Brave Browser", "Contents/MacOS/Chromium", ) 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" # user's home will be the root path of jupyter's file explorer c.ServerApp.root_dir = str(Path.home()) browser_cmd = find_flatpak_browser() or find_browser() 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 " + "in a new tab of the system-default browser" ) # read and exec default config file for additional config/overrides if DEFAULT_CONFIG_FILE.exists(): with open(DEFAULT_CONFIG_FILE, "r") as config_file: exec(config_file.read())