diff --git a/docs/users/jupyterlab/4.2/index.md b/docs/users/jupyterlab/4.2/index.md index d6e8f307ed06c34f9d7e0f9d268a6b1e99e2500a..ffd1e9dd6881151d4058412b534afff235cb182e 100644 --- a/docs/users/jupyterlab/4.2/index.md +++ b/docs/users/jupyterlab/4.2/index.md @@ -1,7 +1,5 @@ # JupyterLab 4.2 -This is the current default version of JupyterLab on Jupyter-JSC. In the next sections we will describe how you can modify it to fit your needs, and give a brief overview of the installed software. - ## Systems Available **JupyterLab 4.2** is available on these systems: diff --git a/docs/users/jupyterlab/4.3/index.md b/docs/users/jupyterlab/4.3/index.md new file mode 100644 index 0000000000000000000000000000000000000000..f4f162565f6821c30901f034f3177666d23107fb --- /dev/null +++ b/docs/users/jupyterlab/4.3/index.md @@ -0,0 +1,93 @@ +# JupyterLab 4.3 + +This is the current default version of JupyterLab on Jupyter-JSC. In the next sections we will describe how you can modify it to fit your needs, and give a brief overview of the installed software. + +## Systems Available + +**JupyterLab 4.3** is available on these systems: + +- **JUWELS** +- **JEDI** +- **JURECA** +- **JUSUF** +- **JSC-Cloud** + +> On **JSC-Cloud** only files in `/home/jovyan` are stored persistently. Everything else will be lost after a restart. + +## Pre-installed kernels +> The kernels listed in this documentation may not always be up-to-date, as they can change periodically. For the current list of available kernels, please check the web service. The configuration files used to install these kernels are stored [here in our GitHub repository](https://github.com/easybuilders/JSC/tree/2025/Golden_Repo/j). + +- [Bash](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-Bash/JupyterKernel-Bash-0.9.3-GCCcore-13.3.0-4.3.4.eb) +- [Cling](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-Cling/JupyterKernel-Cling-1.2-GCCcore-13.3.0-4.3.4.eb) +- [Java](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-Java/JupyterKernel-Java-2.2.0-GCCcore-13.3.0.eb) +- [Julia](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-Julia/JupyterKernel-Julia-1.11.2-GCCcore-13.3.0.eb) +- [LFortran](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-LFortran/JupyterKernel-LFortran-0.42.0-GCCcore-13.3.0.eb) +- [Octave](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-Octave/JupyterKernel-Octave-9.3.0-GCCcore-13.3.0-4.3.4.eb) +- PyHPC +- [PyDeepLearning](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-PyDeepLearning/JupyterKernel-PyDeepLearning-2025.1-GCCcore-13.3.0-4.3.4.eb) +- [PyEarthSystem](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-PyEarthSystem/JupyterKernel-PyEarthSystem-2025.1-GCCcore-13.3.0-4.3.4.eb) +- [PyVisualization](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-PyVisualization/JupyterKernel-PyVisualization-2025.2-GCCcore-13.3.0-4.3.4.eb) +- [R](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-R/JupyterKernel-R-4.4.2-GCCcore-13.3.0-4.2.1.eb) +- [Ruby](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterKernel-Ruby/JupyterKernel-Ruby-3.4.1-GCCcore-13.3.0.eb) + +You can select them by navigating to the **Kernels and Extensions** tab on the left side of your configuration. + +<div style="text-align: center;"> + <img src="../../../images/kernels_and_extensions.png" alt="Kernels" style="width: 70%;"> +</div> + +## Kernel customization + +> It might be easier to create your own environment using [Repo2Docker](../repo2docker/index.md). + +> Since JupyterLab 4.3 uses software loaded via lmod, one cannot simply install a kernel without loading these modules first. Please follow the steps in the these guides to create your own kernel. + +> Having trouble setting up kernels? Check the logs at `/tmp/custom/logs/stdout` in your JupyterLab. + +- [Create kernel with virtualenv on JSC-Cloud](kernels_cloud_venv.ipynb) +- [Create kernel with virtualenv on HPC-Systems](kernels_hpc_venv.ipynb) +- [Create kernel with conda on HPC-Systems](kernels_hpc_conda.ipynb) +- [Create kernel with pyenv on HPC-Systems](kernels_hpc_pyenv.ipynb) +- [Create a containerized kernel with singularity on HPC-Systems](kernels_hpc_singularity.ipynb) +- [Modify or extend a running kernel on HPC-Systems](kernels_hpc_modify_runtime.ipynb) + + +## Extensions +> The extensions listed in this documentation may not always be up-to-date, as they can change periodically. For the current list of available extensions, please check the web service. The configuration files used to install these extensions are stored [here in our GitHub repository](https://github.com/easybuilders/JSC/tree/2025/Golden_Repo/j). + +- Jupyter AI +- [Jupyter Archive](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyter-archive/jupyter-archive-3.4.0-GCCcore-13.3.0.eb) +- [Jupyter Bokeh](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyter-bokeh/jupyter-bokeh-4.0.5-GCCcore-13.3.0.eb) +- [Jupyter Collaboration](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyter-collaboration/jupyter-collaboration-3.1.0-GCCcore-13.3.0.eb) +- [Jupyter Resource Usage](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyter-resource-usage/jupyter-resource-usage-1.1.0-GCCcore-13.3.0.eb) +- [Jupyter Server Proxy](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyter-server-proxy/jupyter-server-proxy-20250303-GCCcore-13.3.0.eb) +- [Jupyter Slurm Provisioner](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyter-slurm-provisioner/jupyter-slurm-provisioner-0.6.0-GCCcore-13.3.0.eb) +- [JupyterLab Code Formatter](https://github.com/easybuilders/JSC/tree/2025/Golden_Repo/j/jupyterlab-code-formatter/jupyterlab-code-formatter-3.0.2-GCCcore-13.3.0.eb) +- [JupyterLab favorites](https://github.com/easybuilders/JSC/tree/2025/Golden_Repo/j/jupyterlab-favorites/jupyterlab-favorites-3.2.2-GCCcore-13.3.0.eb) +- [JupyterLab Git](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyterlab-git/jupyterlab-git-0.50.2-GCCcore-13.3.0.eb) +- [JupyterLab GitHub](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyterlab-github/jupyterlab-github-4.0.0-GCCcore-13.3.0.eb) +- [JupyterLab GitLab](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyterlab-gitlab/jupyterlab-gitlab-4.0.0-GCCcore-13.3.0.eb) +- [JupyterLab H5Web](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyterlab-h5web/jupyterlab-h5web-12.3.0-GCCcore-13.3.0.eb) +- ipyvue +- [Kernel Gateway](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyter-kernel-gateway/jupyter-kernel-gateway-3.0.1-GCCcore-13.3.0.eb) +- [JupyterLab LaTeX](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyterlab-latex/jupyterlab-latex-4.3.0-GCCcore-13.3.0.eb) +- nbdev +- NGLview +- [JupyterLab nvdashboard](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyterlab-nvdashboard/jupyterlab-nvdashboard-0.12.0-GCCcore-13.3.0.eb) +- [JupyterLab Sidecar](https://github.com/easybuilders/JSC/tree/2025/Golden_Repo/j/jupyterlab-sidecar/jupyterlab-sidecar-0.7.0-GCCcore-13.3.0.eb) +- [JupyterLab Spellchecker](https://github.com/easybuilders/JSC/tree/2025/Golden_Repo/j/jupyterlab-spellchecker/jupyterlab-spellchecker-0.8.4-GCCcore-13.3.0.eb) +- [JupyterLab Tour](https://github.com/easybuilders/JSC/tree/2025/Golden_Repo/j/jupyterlab-tour/jupyterlab-tour-4.0.1-GCCcore-13.3.0.eb) +- JupyterLab Trame Manager +- [JupyterLab VariableInspector](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyterlab-variableinspector/jupyterlab-variableinspector-3.2.4-GCCcore-13.3.0.eb) +- [JupyterView](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/jupyterview/jupyterview-0.7.0-GCCcore-13.3.0.eb) +- Voila + +> Most extensions are always loaded. Others can be activated to your liking in the **Kernels and Extensions** tab in your JupyterLab configuration. + + +## Proxies + +- [Xpra Remote Desktop](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterProxy-XpraHTML5/JupyterProxy-XpraHTML5-0.4.3-GCCcore-13.3.0.eb) +- [VSCode](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterProxy-VSCode/JupyterProxy-VSCode-0.9.3-GCCcore-13.3.0.eb) +- [RStudio](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterProxy-RStudio/JupyterProxy-RStudio-2024.12.0-GCCcore-13.3.0.eb) +- [NEST Desktop](https://github.com/easybuilders/JSC/blob/2025/Golden_Repo/j/JupyterProxy-NESTDesktop/JupyterProxy-NESTDesktop-0.4.0-GCCcore-13.3.0.eb) diff --git a/docs/users/jupyterlab/4.3/kernels_cloud_venv.ipynb b/docs/users/jupyterlab/4.3/kernels_cloud_venv.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..031e8377bce314f70de706a6d579c44d78c98246 --- /dev/null +++ b/docs/users/jupyterlab/4.3/kernels_cloud_venv.ipynb @@ -0,0 +1,685 @@ +{ + "cells": [ + { + "attachments": { + "9f53dcb1-00d6-4245-955a-b527f1540865.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": { + "toc-hr-collapsed": false + }, + "source": [ + "\n", + "<h5 style=\"text-align: right\">Author: <a href=\"mailto:j.goebbert@fz-juelich.de?subject=Jupyter4NFDI%20documentation\">Jens Henrik Göbbert</a></h5> \n", + "<h5><a href=\"../index.ipynb\">Index</a></h5>\n", + "<h1 style=\"text-align: center\">Create your own Jupyter Kernel</h1> " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "toc-hr-collapsed": false + }, + "source": [ + "Often the standard kernel do not provide all features you need for your work. This might be that certain modules are not loaded or packages are not installed. \n", + "With your own kernel you can overcome that problem easily and define your own environment, in which you work.\n", + "\n", + "This notebook shows you how you can build your own kernel for a **python environment**.\n", + "\n", + "<div class=\"alert alert-block alert-info\">\n", + "<b>Attention:</b>\n", + "This notebook is meant to run out of a JupyterLab on JSC's HPC systems.</br>\n", + "</div>\n", + "\n", + "-------------------------" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Building your own Jupyter kernel is a three step process\n", + "1. Create/Pimp new virtual Python environment\n", + " * venv\n", + "2. Create/Edit launch script for the Jupyter kernel\n", + " * kernel.sh\n", + "3. Create/Edit Jupyter kernel configuration\n", + " * kernel.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Settings" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Set the kernel name\n", + " - must be lower case\n", + " - change if you like" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mykernel\n" + ] + } + ], + "source": [ + "# INPUT NEEDED:\n", + "KERNEL_NAME=MyKernel\n", + "\n", + "export KERNEL_NAME=$(echo \"${KERNEL_NAME}\" | awk '{print tolower($0)}')\n", + "echo ${KERNEL_NAME} # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Set the kernel directory\n", + " - check that the kernel name is unique\n", + " - print the location of the new kernel" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jovyan/.local/share/jupyter/kernels/mykernel\n" + ] + } + ], + "source": [ + "# define KERNEL_SPECS_DIR\n", + "export KERNEL_SPECS_PREFIX=${HOME}/.local\n", + "if [ ! -d \"$KERNEL_SPECS_PREFIX\" ]; then\n", + " echo \"ERROR: please create directory $KERNEL_SPECS_PREFIX\"\n", + "fi\n", + "export KERNEL_SPECS_DIR=${KERNEL_SPECS_PREFIX}/share/jupyter/kernels\n", + "\n", + "# check if kernel name is unique\n", + "if [ -d \"${KERNEL_SPECS_DIR}/${KERNEL_NAME}\" ]; then\n", + " echo \"ERROR: Kernel already exists in ${KERNEL_SPECS_DIR}/${KERNEL_NAME}\"\n", + " echo \" Rename kernel name or remove directory.\"\n", + "fi\n", + "\n", + "# print the location of the new kernel\n", + "echo ${KERNEL_SPECS_DIR}/${KERNEL_NAME} " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Set the kernel's virtual environment\n", + " - by default it is located at $PROJECT\n", + " - print the location of the new kernels virtual environment" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jovyan/jupyter/kernels\n" + ] + } + ], + "source": [ + "# define KERNEL_VENVS_DIR\n", + "export KERNEL_VENVS_DIR=/home/jovyan/jupyter/kernels\n", + "mkdir -p ${KERNEL_VENVS_DIR}\n", + "\n", + "# print the location of the new kernels virtual environment\n", + "echo ${KERNEL_VENVS_DIR}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Create/Pimp new virtual Python environment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.1 - Load basic Python module" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The following modules were not unloaded:\n", + " (Use \"module --force purge\" to unload all):\n", + "\n", + " 1) Stages/2025\n" + ] + } + ], + "source": [ + "module purge\n", + "module load Stages/2025 # any stage can be used\n", + "module load GCC\n", + "module load Python # only Python is mandatory" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3.12\n" + ] + } + ], + "source": [ + "# get Python version\n", + "export PYV=$(python -c 'import sys; print(\".\".join(map(str, sys.version_info[:2])))')\n", + "echo $PYV" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.2 - Load extra modules you need for your kernel" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# module load <module you need>" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.3 - Create and activate a virtual environment for the kernel \n", + "and ensure python packages installed in the virtual environment are always prefered" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/jovyan/jupyter/kernels/mykernel\n" + ] + } + ], + "source": [ + "export VIRTUAL_ENV=${KERNEL_VENVS_DIR}/${KERNEL_NAME}\n", + "if [ -d \"${VIRTUAL_ENV}\" ]; then\n", + " echo \"ERROR: Directory for virtual environment already ${VIRTUAL_ENV}\"\n", + " echo \" Rename kernel name or remove directory.\"\n", + "else\n", + " python -m venv --system-site-packages ${VIRTUAL_ENV}\n", + " source ${VIRTUAL_ENV}/bin/activate\n", + " export PYTHONPATH=${VIRTUAL_ENV}/lib/python${PYV}/site-packages:${PYTHONPATH}\n", + " echo ${VIRTUAL_ENV} # double check\n", + "fi" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.4 - Install Python libraries required for communication with Jupyter" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "~/jupyter/kernels/mykernel/bin/pip\n", + "Collecting ipykernel\n", + " Downloading ipykernel-6.29.5-py3-none-any.whl.metadata (6.3 kB)\n", + "Collecting comm>=0.1.1 (from ipykernel)\n", + " Downloading comm-0.2.2-py3-none-any.whl.metadata (3.7 kB)\n", + "Collecting debugpy>=1.6.5 (from ipykernel)\n", + " Downloading debugpy-1.8.13-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (1.3 kB)\n", + "Collecting ipython>=7.23.1 (from ipykernel)\n", + " Downloading ipython-9.0.2-py3-none-any.whl.metadata (4.3 kB)\n", + "Collecting jupyter-client>=6.1.12 (from ipykernel)\n", + " Downloading jupyter_client-8.6.3-py3-none-any.whl.metadata (8.3 kB)\n", + "Collecting jupyter-core!=5.0.*,>=4.12 (from ipykernel)\n", + " Downloading jupyter_core-5.7.2-py3-none-any.whl.metadata (3.4 kB)\n", + "Collecting matplotlib-inline>=0.1 (from ipykernel)\n", + " Downloading matplotlib_inline-0.1.7-py3-none-any.whl.metadata (3.9 kB)\n", + "Collecting nest-asyncio (from ipykernel)\n", + " Downloading nest_asyncio-1.6.0-py3-none-any.whl.metadata (2.8 kB)\n", + "Requirement already satisfied: packaging in /p/software/jsccloud/stages/2025/software/Python/3.12.3-GCCcore-13.3.0/lib/python3.12/site-packages (from ipykernel) (24.0)\n", + "Collecting psutil (from ipykernel)\n", + " Downloading psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (22 kB)\n", + "Collecting pyzmq>=24 (from ipykernel)\n", + " Downloading pyzmq-26.3.0-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (6.2 kB)\n", + "Collecting tornado>=6.1 (from ipykernel)\n", + " Downloading tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (2.5 kB)\n", + "Collecting traitlets>=5.4.0 (from ipykernel)\n", + " Downloading traitlets-5.14.3-py3-none-any.whl.metadata (10 kB)\n", + "Collecting decorator (from ipython>=7.23.1->ipykernel)\n", + " Downloading decorator-5.2.1-py3-none-any.whl.metadata (3.9 kB)\n", + "Collecting ipython-pygments-lexers (from ipython>=7.23.1->ipykernel)\n", + " Downloading ipython_pygments_lexers-1.1.1-py3-none-any.whl.metadata (1.1 kB)\n", + "Collecting jedi>=0.16 (from ipython>=7.23.1->ipykernel)\n", + " Downloading jedi-0.19.2-py2.py3-none-any.whl.metadata (22 kB)\n", + "Collecting pexpect>4.3 (from ipython>=7.23.1->ipykernel)\n", + " Downloading pexpect-4.9.0-py2.py3-none-any.whl.metadata (2.5 kB)\n", + "Collecting prompt_toolkit<3.1.0,>=3.0.41 (from ipython>=7.23.1->ipykernel)\n", + " Downloading prompt_toolkit-3.0.50-py3-none-any.whl.metadata (6.6 kB)\n", + "Collecting pygments>=2.4.0 (from ipython>=7.23.1->ipykernel)\n", + " Downloading pygments-2.19.1-py3-none-any.whl.metadata (2.5 kB)\n", + "Collecting stack_data (from ipython>=7.23.1->ipykernel)\n", + " Downloading stack_data-0.6.3-py3-none-any.whl.metadata (18 kB)\n", + "Collecting python-dateutil>=2.8.2 (from jupyter-client>=6.1.12->ipykernel)\n", + " Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)\n", + "Collecting platformdirs>=2.5 (from jupyter-core!=5.0.*,>=4.12->ipykernel)\n", + " Downloading platformdirs-4.3.7-py3-none-any.whl.metadata (11 kB)\n", + "Collecting parso<0.9.0,>=0.8.4 (from jedi>=0.16->ipython>=7.23.1->ipykernel)\n", + " Downloading parso-0.8.4-py2.py3-none-any.whl.metadata (7.7 kB)\n", + "Collecting ptyprocess>=0.5 (from pexpect>4.3->ipython>=7.23.1->ipykernel)\n", + " Downloading ptyprocess-0.7.0-py2.py3-none-any.whl.metadata (1.3 kB)\n", + "Collecting wcwidth (from prompt_toolkit<3.1.0,>=3.0.41->ipython>=7.23.1->ipykernel)\n", + " Downloading wcwidth-0.2.13-py2.py3-none-any.whl.metadata (14 kB)\n", + "Collecting six>=1.5 (from python-dateutil>=2.8.2->jupyter-client>=6.1.12->ipykernel)\n", + " Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)\n", + "Collecting executing>=1.2.0 (from stack_data->ipython>=7.23.1->ipykernel)\n", + " Downloading executing-2.2.0-py2.py3-none-any.whl.metadata (8.9 kB)\n", + "Collecting asttokens>=2.1.0 (from stack_data->ipython>=7.23.1->ipykernel)\n", + " Downloading asttokens-3.0.0-py3-none-any.whl.metadata (4.7 kB)\n", + "Collecting pure-eval (from stack_data->ipython>=7.23.1->ipykernel)\n", + " Downloading pure_eval-0.2.3-py3-none-any.whl.metadata (6.3 kB)\n", + "Downloading ipykernel-6.29.5-py3-none-any.whl (117 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m117.2/117.2 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading comm-0.2.2-py3-none-any.whl (7.2 kB)\n", + "Downloading debugpy-1.8.13-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.2 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.2/4.2 MB\u001b[0m \u001b[31m19.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", + "\u001b[?25hDownloading ipython-9.0.2-py3-none-any.whl (600 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m600.5/600.5 kB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", + "\u001b[?25hDownloading jupyter_client-8.6.3-py3-none-any.whl (106 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m106.1/106.1 kB\u001b[0m \u001b[31m4.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading jupyter_core-5.7.2-py3-none-any.whl (28 kB)\n", + "Downloading matplotlib_inline-0.1.7-py3-none-any.whl (9.9 kB)\n", + "Downloading pyzmq-26.3.0-cp312-cp312-manylinux_2_28_x86_64.whl (859 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m859.9/859.9 kB\u001b[0m \u001b[31m6.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", + "\u001b[?25hDownloading tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (437 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m437.2/437.2 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", + "\u001b[?25hDownloading traitlets-5.14.3-py3-none-any.whl (85 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m85.4/85.4 kB\u001b[0m \u001b[31m3.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading nest_asyncio-1.6.0-py3-none-any.whl (5.2 kB)\n", + "Downloading psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (277 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m278.0/278.0 kB\u001b[0m \u001b[31m4.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", + "\u001b[?25hDownloading jedi-0.19.2-py2.py3-none-any.whl (1.6 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m18.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", + "\u001b[?25hDownloading pexpect-4.9.0-py2.py3-none-any.whl (63 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m63.8/63.8 kB\u001b[0m \u001b[31m2.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading platformdirs-4.3.7-py3-none-any.whl (18 kB)\n", + "Downloading prompt_toolkit-3.0.50-py3-none-any.whl (387 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m387.8/387.8 kB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", + "\u001b[?25hDownloading pygments-2.19.1-py3-none-any.whl (1.2 MB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.2/1.2 MB\u001b[0m \u001b[31m9.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m0:00:01\u001b[0m\n", + "\u001b[?25hDownloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m229.9/229.9 kB\u001b[0m \u001b[31m2.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m\n", + "\u001b[?25hDownloading decorator-5.2.1-py3-none-any.whl (9.2 kB)\n", + "Downloading ipython_pygments_lexers-1.1.1-py3-none-any.whl (8.1 kB)\n", + "Downloading stack_data-0.6.3-py3-none-any.whl (24 kB)\n", + "Downloading asttokens-3.0.0-py3-none-any.whl (26 kB)\n", + "Downloading executing-2.2.0-py2.py3-none-any.whl (26 kB)\n", + "Downloading parso-0.8.4-py2.py3-none-any.whl (103 kB)\n", + "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m103.7/103.7 kB\u001b[0m \u001b[31m4.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25hDownloading ptyprocess-0.7.0-py2.py3-none-any.whl (13 kB)\n", + "Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)\n", + "Downloading pure_eval-0.2.3-py3-none-any.whl (11 kB)\n", + "Downloading wcwidth-0.2.13-py2.py3-none-any.whl (34 kB)\n", + "Installing collected packages: wcwidth, pure-eval, ptyprocess, traitlets, tornado, six, pyzmq, pygments, psutil, prompt_toolkit, platformdirs, pexpect, parso, nest-asyncio, executing, decorator, debugpy, asttokens, stack_data, python-dateutil, matplotlib-inline, jupyter-core, jedi, ipython-pygments-lexers, comm, jupyter-client, ipython, ipykernel\n", + "Successfully installed asttokens-3.0.0 comm-0.2.2 debugpy-1.8.13 decorator-5.2.1 executing-2.2.0 ipykernel-6.29.5 ipython-9.0.2 ipython-pygments-lexers-1.1.1 jedi-0.19.2 jupyter-client-8.6.3 jupyter-core-5.7.2 matplotlib-inline-0.1.7 nest-asyncio-1.6.0 parso-0.8.4 pexpect-4.9.0 platformdirs-4.3.7 prompt_toolkit-3.0.50 psutil-7.0.0 ptyprocess-0.7.0 pure-eval-0.2.3 pygments-2.19.1 python-dateutil-2.9.0.post0 pyzmq-26.3.0 six-1.17.0 stack_data-0.6.3 tornado-6.4.2 traitlets-5.14.3 wcwidth-0.2.13\n", + "\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m25.0.1\u001b[0m\n", + "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" + ] + } + ], + "source": [ + "which pip\n", + "if [ -z \"${VIRTUAL_ENV}\" ]; then\n", + " echo \"ERROR: Virtual environment not successfully initialized.\"\n", + "else\n", + " pip install ipykernel\n", + "fi" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.5 - Install whatever else you need in your Python virtual environment (using pip)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#pip install <python-package you need>" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Create/Edit launch script for the Jupyter kernel" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 2.1 - Create launch script, which loads your Python virtual environment and starts the ipykernel process inside:\n", + "\n", + "<div class=\"alert alert-block alert-info\">\n", + "<b>Attention:</b>\n", + "You MUST load the exactly the same modules as you did above for your virtual Python environment.\n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "#!/bin/bash\n", + "\n", + "# Load basic Python module\n", + "module purge\n", + "module load Stages/2025\n", + "module load GCC\n", + "module load Python\n", + "\n", + "# Load extra modules you need for your kernel (as you did in step 1.2)\n", + "#module load <module you need>\n", + "\n", + "# Activate your Python virtual environment\n", + "source /home/jovyan/jupyter/kernels/mykernel/bin/activate\n", + " \n", + "# Ensure python packages installed in the virtual environment are always prefered\n", + "export PYTHONPATH=/home/jovyan/jupyter/kernels/mykernel/lib/python3.12/site-packages:${PYTHONPATH}\n", + " \n", + "exec python -m ipykernel $@\n" + ] + } + ], + "source": [ + "echo '#!/bin/bash'\"\n", + "\n", + "# Load basic Python module\n", + "module purge\n", + "module load Stages/2025\n", + "module load GCC\n", + "module load Python\n", + "\n", + "# Load extra modules you need for your kernel (as you did in step 1.2)\n", + "#module load <module you need>\n", + "\n", + "# Activate your Python virtual environment\n", + "source ${VIRTUAL_ENV}/bin/activate\n", + " \n", + "# Ensure python packages installed in the virtual environment are always prefered\n", + "export PYTHONPATH=${VIRTUAL_ENV}/lib/python${PYV}/site-packages:\"'${PYTHONPATH}'\"\n", + " \n", + "exec python -m ipykernel \"'$@' > ${VIRTUAL_ENV}/kernel.sh\n", + "chmod +x ${VIRTUAL_ENV}/kernel.sh\n", + "\n", + "cat ${VIRTUAL_ENV}/kernel.sh # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Create/Edit Jupyter kernel configuration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.1 - Create Jupyter kernel configuration directory and files" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installed kernelspec mykernel in /home/jovyan/jupyter/kernels/mykernel/share/jupyter/kernels/mykernel\n" + ] + } + ], + "source": [ + "python -m ipykernel install --name=${KERNEL_NAME} --prefix ${VIRTUAL_ENV}\n", + "export VIRTUAL_ENV_KERNELS=${VIRTUAL_ENV}/share/jupyter/kernels" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.2 - Adjust kernel.json file" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"argv\": [\n", + " \"/home/jovyan/jupyter/kernels/mykernel/kernel.sh\",\n", + " \"-m\",\n", + " \"ipykernel_launcher\",\n", + " \"-f\",\n", + " \"{connection_file}\"\n", + " ],\n", + " \"display_name\": \"mykernel\",\n", + " \"language\": \"python\",\n", + " \"metadata\": {\n", + " \"debugger\": true\n", + " }\n", + "}\n" + ] + } + ], + "source": [ + "mv ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME}/kernel.json ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME}/kernel.json.orig\n", + "\n", + "echo '{\n", + " \"argv\": [\n", + " \"'${KERNEL_VENVS_DIR}/${KERNEL_NAME}/kernel.sh'\",\n", + " \"-m\",\n", + " \"ipykernel_launcher\",\n", + " \"-f\",\n", + " \"{connection_file}\"\n", + " ],\n", + " \"display_name\": \"'${KERNEL_NAME}'\",\n", + " \"language\": \"python\",\n", + " \"metadata\": {\n", + " \"debugger\": true\n", + " }\n", + "}' > ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME}/kernel.json\n", + "\n", + "cat ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME}/kernel.json # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.3 - Create link to kernel specs" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "The new kernel 'mykernel' was added to your kernels in '/home/jovyan/.local/share/jupyter/kernels/'\n", + "\n", + "abc mykernel\n" + ] + } + ], + "source": [ + "mkdir -p ${KERNEL_SPECS_DIR}\n", + "cd ${KERNEL_SPECS_DIR}\n", + "ln -s ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME} .\n", + "\n", + "echo -e \"\\n\\nThe new kernel '${KERNEL_NAME}' was added to your kernels in '${KERNEL_SPECS_DIR}/'\\n\"\n", + "ls ${KERNEL_SPECS_DIR} # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.4 - Use the kernel\n", + "- You can select the new kernel in the top right corner of your notebook or from JupyterLab's Launchpad\n", + "- The kernel icon will be added to your launcher, after a while by JupyterLab automatically or once you've restarted the JupyterLab" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Cleanup" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "deactivate" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Bash", + "language": "bash", + "name": "bash" + }, + "language_info": { + "codemirror_mode": "shell", + "file_extension": ".sh", + "mimetype": "text/x-sh", + "name": "bash" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/users/jupyterlab/4.3/kernels_hpc_conda.ipynb b/docs/users/jupyterlab/4.3/kernels_hpc_conda.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..1cad3294042dd2872ce468578ceab45b39abf995 --- /dev/null +++ b/docs/users/jupyterlab/4.3/kernels_hpc_conda.ipynb @@ -0,0 +1,318 @@ +{ + "cells": [ + { + "attachments": { + "364f4d26-8fd6-45ed-a6c3-1ab27dad25c4.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": { + "toc-hr-collapsed": false + }, + "source": [ + "\n", + "<h5 style=\"text-align: right\">Author: <a href=\"mailto:s.luehrs@fz-juelich.de?subject=Jupyter-JSC%20documentation\">Sebastian Lührs</a></h5> \n", + "<h5><a href=\"../index.ipynb\">Index</a></h5>\n", + "<h1 style=\"text-align: center\">Create your own Jupyter CONDA-Kernel</h1> " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Often the standard kernel do not provide all features you need for your work. This might be that certain modules are not loaded or packages are not installed.\n", + "With your own kernel you can overcome that problem easily and define your own environment, in which you work.\n", + "\n", + "This notebook shows you how you can build your own kernel for a **conda environment**.\n", + "\n", + "--------------------------------------" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Building your own Jupyter CONDA-kernel is a three step process\n", + "Download Minconda installer\n", + "1. Download/Install Miniconda\n", + " * Miniconda3.sh\n", + "2. Create Conda Environment\n", + " * conda create\n", + "2. Create/Edit launch script for the Jupyter kernel\n", + " * kernel.sh\n", + "3. Create/Edit Jupyter kernel configuration\n", + " * kernel.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Settings" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Selectable **CONDA_ENV** name, will be used to specify the environment name\n", + " - must be lowercase" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "CONDA_ENV=my_condaenv\n", + "\n", + "export CONDA_ENV=$(echo \"${CONDA_ENV}\" | awk '{print tolower($0)}')\n", + "echo ${CONDA_ENV} # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Selectable **CONDA_TARGET_DIR** path for the central conda installation, should be in the project filesystem" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "export CONDA_TARGET_DIR=${PROJECT}/${USER}/miniconda3/${CONDA_ENV}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## 1. Download/Install Miniconda" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Start here if you want to run the full installation.\n", + "If you want to create another environment in an existing conda setup go to **create environment**. If you want to attach yourself to an existing environment go to **create user kernel**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 1.1 - Download Minconda installer" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "wget --output-document=$HOME/Miniconda3.sh https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 1.2 - Create target directory" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mkdir -p ${CONDA_TARGET_DIR}\n", + "echo ${CONDA_TARGET_DIR}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 1.3 - Install Miniconda" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "unset PYTHONPATH\n", + "bash $HOME/Miniconda3.sh -b -u -p ${CONDA_TARGET_DIR}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 1.4 - Disable automatic activation \n", + "Create `~/.condarc` and add the configuration settings." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "${CONDA_TARGET_DIR}/bin/conda config --set auto_activate_base false" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## 2. Create conda environment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create new conda environment. The following steps can be repeated if multiple environments should be created. If the Python version differ towards the external Python version, a mix of Conda modules and external modules will not be possible" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "${CONDA_TARGET_DIR}/bin/conda create -n ${CONDA_ENV} -y python=3.11.3 ipykernel" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## 3. Create/Edit launch script for the Jupyter kernel" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 3.1 - Create kernel to allow access to the conda environment. Adapte `module purge` and `PYTHONPATH` according to the comments." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "echo '#!/bin/bash\n", + "\n", + "# module purge # optional to disable the external environment, necessary, if python version is different\n", + " \n", + "# Activate your Python virtual environment\n", + "source '\"${CONDA_TARGET_DIR}\"'/bin/activate '\"${CONDA_ENV}\"'\n", + " \n", + "# Ensure python packages installed in conda are always prefered, not necessary if module purge is used\n", + "export PYTHONPATH=${CONDA_PREFIX}/lib/python3.11/site-packages:${PYTHONPATH}\n", + " \n", + "exec python -m ipykernel $@' > ${CONDA_TARGET_DIR}/envs/${CONDA_ENV}/kernel.sh" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "chmod +x ${CONDA_TARGET_DIR}/envs/${CONDA_ENV}/kernel.sh\n", + "echo ${CONDA_TARGET_DIR}/envs/${CONDA_ENV}/kernel.sh" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## 4. Create/Edit Jupyter kernel configuration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 4.1 - Create user kernel, if you want to access the conda environment of a colleague, only these steps are necessary" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mkdir -p $HOME/.local/share/jupyter/kernels/conda_${CONDA_ENV}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 4.2 - Adjust kernel.json file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "echo '{\n", + " \"argv\": [\n", + " \"'\"${CONDA_TARGET_DIR}\"'/envs/'\"${CONDA_ENV}\"'/kernel.sh\",\n", + " \"-f\",\n", + " \"{connection_file}\"\n", + " ],\n", + " \"display_name\": \"conda_'\"${CONDA_ENV}\"'\",\n", + " \"language\": \"python\",\n", + " \"metadata\": {\n", + " \"debugger\": true\n", + " }\n", + "}' > $HOME/.local/share/jupyter/kernels/conda_${CONDA_ENV}/kernel.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Restart of JupyterLab might be necessary to see the kernel in the kernel selection overview." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Bash", + "language": "bash", + "name": "bash" + }, + "language_info": { + "codemirror_mode": "shell", + "file_extension": ".sh", + "mimetype": "text/x-sh", + "name": "bash" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/users/jupyterlab/4.3/kernels_hpc_modify_runtime.ipynb b/docs/users/jupyterlab/4.3/kernels_hpc_modify_runtime.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..8f6ad8cf904e836927a2da5a3b36c9736f414204 --- /dev/null +++ b/docs/users/jupyterlab/4.3/kernels_hpc_modify_runtime.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "attachments": { + "03fec242-e656-439b-b99a-8941fcb58603.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "<h5 style=\"text-align: right\">Author: <a href=\"mailto:j.windgassen@fz-juelich.de?subject=Jupyter-JSC%20documentation\">Jonathan Windgassen</a></h5> \n", + "<h5><a href=\"../index.ipynb\">Index</a></h5>\n", + "<h1 style=\"text-align: center\">How to modify/extend a running Jupyter Kernel</h1> " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are many cases where one needs modules from JupyterLab for a project. But building your own kernel is often a detour from the original idea or is annoying when publishing your project. \n", + "By adding these 4 cells to the top of your project you can load modules for the project \"on the fly\".\n", + "\n", + "Besides that this also adds a ways of installing python packages via pip without disrupting the uses packages or access to the system site-packages\n", + "\n", + "-------" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- First we create to temp-folders in the */tmp* directory, who will contain the venv where we install the required packages and a folder that stores the PYTHONPATH and LD_LIBRARY_PATH environment variable. This is necessary because loading modules manipulates these variables but we can't access the changes from within python, so we store the changed variables in a folder.\n", + "- Then we use a bash-shell to:\n", + " - Load the Modules\n", + " - Create a venv and installing ipykernel in there\n", + " - Write PYTHONPATH and LD_LIBRARY_PATH to the tempdir\n", + "- Beacause the Dynamic Linker of Python doesn't detect changes in LD_LIBRARY_PATH we need to reboot the Interpreter afterwards to carry these changes over. To gain access to the venv we will start Python from there.\n", + "- After that we install the required modules.\n", + "\n", + "**Note**: The third cell **won't** show that it's completed and the Notebook will show `Python 3 | Starting` at the bottom, although the interpreter already reloaded compeltely. You can savely ignore this and continue with the third shell. As soon as this has finished the Notebook will show `Python3 | Idle` again." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os, sys, tempfile\n", + "\n", + "tempdir = tempfile.mkdtemp()\n", + "venv_folder = tempfile.mkdtemp()\n", + "print(tempdir, venv_folder)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%bash -s \"$tempdir\" \"$venv_folder\" # Pass the paths to the bash-subshell\n", + "\n", + "######################################################################\n", + "## The modules go here ##\n", + "## We will use Stage/Devel-2020 with Python 3.8 as a example ##\n", + "######################################################################\n", + "\n", + "# Update to Stage Devel-2020\n", + "module --force purge\n", + "module use $OTHERSTAGES \n", + "module load Stages/Devel-2020\n", + "\n", + "module load GCC/9.3.0\n", + "module load Python/3.8.5\n", + "\n", + "# Create a venv with the python from Devel-2020 and install ipykernel there (needed for communicating with Jupyter)\n", + "# If you don't change Python above this should be a normal Python 3.6 venv\n", + "python -m venv --system-site-packages $2\n", + "source $2/bin/activate\n", + "pip install --quiet ipykernel\n", + "\n", + "# Store the new variables to the temp-folder\n", + "echo $PYTHONPATH > $1/pythonpath\n", + "echo $LD_LIBRARY_PATH > $1/librarypath" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# The arguments for the new python interpreter. We need to initialize ipykernel or JupyterLab will fail to integrate the new process\n", + "args = [f\"{venv_folder}/bin/python\", \"-m\", \"ipykernel\"]\n", + "args.extend(sys.argv)\n", + "\n", + "# Because we call \"execve\" instead of \"execv\" we get the option to set the environment variables in the process. We use this to smuggle in the changed LD_LIBRARY_PATH and PYTHONPATH.\n", + "# You also can pass the location of the 2 temp-folders as new environment variables if you want to delete them later for cleanup.\n", + "env = {\"PYTHONPATH\": open(f\"{tempdir}/pythonpath\").read(),\n", + " \"LD_LIBRARY_PATH\": open(f\"{tempdir}/librarypath\").read(),\n", + " \"tempdir\": tempdir,\n", + " \"venv_folder\": venv_folder}\n", + " \n", + "!echo Restarting Interpreter from $venv_folder/bin/python. Please execute the next cell\n", + "os.execve(f\"{venv_folder}/bin/python\", args, env)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Because we are in the venv now, we can safely install all packages that we need and don't come with the Python3-Kernel. No need to add --user\n", + "%pip install --quiet ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "-----\n", + "\n", + "After that you can import all you libraries (remember that the Interpreter restarted and you need to reimport os/sys/tempfile if you need them) and start with the notebook" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/users/jupyterlab/4.3/kernels_hpc_pyenv.ipynb b/docs/users/jupyterlab/4.3/kernels_hpc_pyenv.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..b1aee1885ffb17bfccd96d541c58234b67e0718b --- /dev/null +++ b/docs/users/jupyterlab/4.3/kernels_hpc_pyenv.ipynb @@ -0,0 +1,497 @@ +{ + "cells": [ + { + "attachments": { + "500ad0ee-8923-43bb-9336-e838a26dc2f1.jpg": { + "image/jpeg": "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" + } + }, + "cell_type": "markdown", + "metadata": { + "toc-hr-collapsed": false + }, + "source": [ + " \n", + "Author: [Filipe Guimaraes](mailto:f.guimaraes@fz-juelich.de)\n", + "--------------------------------------" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create your own Jupyter pyenv-Kernel\n", + "\n", + "Often the standard kernel do not provide all features you need for your work. This might be that certain modules are not loaded or packages are not installed.\n", + "With your own kernel you can overcome that problem easily and define your own environment, in which you work.\n", + "\n", + "This notebook shows you how you can build your own kernel for a **pyenv environment**.\n", + "\n", + "--------------------------------------" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Building your own Jupyter pyenv-kernel is a four-step process\n", + "\n", + "1. **[Download/Install pyenv](#install)**: To start from scratch, and run the full installation.\n", + "2. **[Create and setup environment](#environment)**: To create an(other) environment in an existing pyenv setup. \n", + "If `pyenv` is already installed, start here.\n", + "3. **[Create/Edit launch script for the Jupyter kernel](#kernel)**: To setup an environment to be run via Jupyter. \n", + "If the environment already exists, start here.\n", + "4. **[Create/Edit Jupyter kernel configuration](#json)**: To attach your user to an existing environment via Jupyter. \n", + "If the kernel launch script was already created (e.g., by some other user in the project), start here." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='settings'></a>\n", + "### Settings" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To simplifly the process, it is convenient to define a **PYENV_ROOT** path for the central pyenv installation and put on the PATH. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Important**: It is recommended to use a folder inside the `$PROJECT` file system, as the `$HOME` quota is low. It is also useful to share installation for different users in a single project." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "export PYENV_ROOT=${PROJECT_<projectid>}/${USER}/.pyenv\n", + "export PATH=\"$PYENV_ROOT/bin:$PATH\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Also the environment name can be set in an environment variable **PYENV_ENV** to simplify the process:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "export PYENV_ENV=my_env" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "<a id='install'></a>\n", + "## 1. Download/Install pyenv" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Installing and setting up pyenv from scratch is very simple. A simple command is needed to install pyenv in **$PYENV_ROOT**:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "curl https://pyenv.run | bash" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "<a id='environment'></a>\n", + "## 2. Create and setup pyenv environment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following steps describe how to create and setup a new pyenv environment to be used as a jupyter kernel. They can be repeated if multiple environments are required." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For these steps, make sure to have a clean environment before starting this process. This can be obtained by running `module purge`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "$ module purge\n", + "$ module list\n", + "\n", + "Currently Loaded Modules:\n", + " 1) Stages/2020 (S)\n", + "\n", + " Where:\n", + " S: Module is Sticky, requires --force to unload or purge" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 2.1 - Activate pyenv and virtual envs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Activate pyenv and the virtual environments by running:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "eval \"$(pyenv init --path)\"\n", + "eval \"$(pyenv init -)\"\n", + "eval \"$(pyenv virtualenv-init -)\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 2.2 - Install a python version (e.g. `3.10.1`)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pyenv install 3.10.1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note: This step may take a few minutes to complete the installation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 2.3 - Create a new environment **$PYENV_ENV** (defined in **[Settings section](#settings)**)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The environment is created using the python version installed above" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pyenv virtualenv 3.10.1 $PYENV_ENV" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 2.4 - Activate and setup the environment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Jupyter requires the `ipykernel` module and its dependencies. To install them, first activate the environment:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pyenv activate $PYENV_ENV" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "When the environment is successfully activated, the name of the environment is shown between parenthesis in the command line, e.g. `(my_env)`. (To deactivate the environment, use `pyenv deactivate $PYENV_ENV`.)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The python version can be checked using" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(my_env)$ python --version\n", + "Python 3.10.1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The list of python modules is still empty" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(my_env)$ pip list\n", + "Package Version\n", + "---------- -------\n", + "pip 21.2.4\n", + "setuptools 58.1.0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To create a Jupyter kernel, the `ipykernel` and its dependencies are required. `pip` can be used to install it:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "pip install ipykernel" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Many modules are installed:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "(my_env)$ pip list\n", + "Package Version\n", + "----------------- -------\n", + "backcall 0.2.0\n", + "debugpy 1.5.1\n", + "decorator 5.1.1\n", + "entrypoints 0.3\n", + "ipykernel 6.6.1\n", + "ipython 7.31.0\n", + "jedi 0.18.1\n", + "jupyter-client 7.1.0\n", + "jupyter-core 4.9.1\n", + "matplotlib-inline 0.1.3\n", + "nest-asyncio 1.5.4\n", + "parso 0.8.3\n", + "pexpect 4.8.0\n", + "pickleshare 0.7.5\n", + "pip 21.1.1\n", + "prompt-toolkit 3.0.24\n", + "ptyprocess 0.7.0\n", + "Pygments 2.11.2\n", + "python-dateutil 2.8.2\n", + "pyzmq 22.3.0\n", + "setuptools 56.0.0\n", + "six 1.16.0\n", + "tornado 6.1\n", + "traitlets 5.1.1\n", + "wcwidth 0.2.5" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "<a id='kernel'></a>\n", + "## 3. Create/Edit launch script for the Jupyter kernel" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following steps describe how to create and configure the launch script of a new Jupyter kernel using a pyenv environment. If the environment was created in the $PROJECT folder, many users of the project can follow these steps to create the kernel. The steps assume the variables described in the **[Settings section](#settings)** are set up." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "<a id='launch'></a>\n", + "* 3.1 - Create kernel script to allow access to the pyenv environment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "echo '#!/bin/bash\n", + "\n", + "module purge\n", + "\n", + "export PYENV_ROOT='\"$PYENV_ROOT\"'\n", + "export PATH='\"$PYENV_ROOT\"'/bin:'\"$PATH\"'\n", + "eval \"$(pyenv init --path)\"\n", + "eval \"$(pyenv init -)\"\n", + "eval \"$(pyenv virtualenv-init -)\"\n", + "\n", + "# Activate your Python virtual environment\n", + "pyenv activate '\"${PYENV_ENV}\"'\n", + "\n", + "exec python -m ipykernel $@' > ${PYENV_ROOT}/versions/${PYENV_ENV}/kernel.sh" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add executable permission to the script:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "chmod +x ${PYENV_ROOT}/versions/${PYENV_ENV}/kernel.sh" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "## 4. Create/Edit Jupyter kernel configuration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These steps describe how to create a Jupyter kernel configuration file, to be able to access the environment via a Jupyter notebook. To access an existing pyenv environment located in **$PROJECT**, only these steps are necessary. The steps assume the variables described in the **[Settings section](#settings)** are set up." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 4.1 - Create a folder for the kernel" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mkdir -p $HOME/.local/share/jupyter/kernels/pyenv_${PYENV_ENV}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* 4.2 - Create and adjust the kernel.json file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "echo '{\n", + " \"argv\": [\n", + " \"'\"${PYENV_ROOT}\"'/versions/'\"${PYENV_ENV}\"'/kernel.sh\",\n", + " \"-f\",\n", + " \"{connection_file}\"\n", + " ],\n", + " \"display_name\": \"pyenv_'\"${PYENV_ENV}\"'\",\n", + " \"language\": \"python\"\n", + "}' > $HOME/.local/share/jupyter/kernels/pyenv_${PYENV_ENV}/kernel.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Restart of JupyterLab might be necessary to see the kernel in the kernel selection overview." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Bash", + "language": "bash", + "name": "bash" + }, + "language_info": { + "codemirror_mode": "shell", + "file_extension": ".sh", + "mimetype": "text/x-sh", + "name": "bash" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/users/jupyterlab/4.3/kernels_hpc_singularity.ipynb b/docs/users/jupyterlab/4.3/kernels_hpc_singularity.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..cfbe7904449a8ae5a7f9eae1bd4c6fb6e56bf4eb --- /dev/null +++ b/docs/users/jupyterlab/4.3/kernels_hpc_singularity.ipynb @@ -0,0 +1,317 @@ +{ + "cells": [ + { + "attachments": { + "dee407d8-ed50-42d4-8200-c39761fee461.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "<!--<h5 style=\"text-align: right\">Author: <a href=\"mailto:@fz-juelich.de?subject=Jupyter-JSC%20documentation\"></a></h5>--><h5 style=\"text-align: right\">Author: Katharina Höflich</h5> \n", + "<h5><a href=\"../index.ipynb\">Index</a></h5>\n", + "<h1 style=\"text-align: center\">Install containerized Jupyter kernel at Jupyter-JSC</h1> " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This Jupyter notebook will walk you through the installation of a containerized Jupyter kernel (for use at Jupyter-JSC, but it should actually work with any Jupyter server on a system where Singularity is installed). Considerable performance improvements (especially with respect to kernel start-up times) over e.g. conda-based Jupyter kernels on distributed filesystems, as are typically installed on HPC systems, might be experienced. In the example below, the `base-notebook` from the [Jupyter docker stacks](https://jupyter-docker-stacks.readthedocs.io/en/latest/) is used as an IPython kernel (already having the required `ipykernel` package installed), the approach presented here might be extended to any other [Jupyter kernel compatible programming language](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels), though.\n", + "\n", + "Requirements:\n", + "\n", + "* Python environment with an installed `ipykernel` package in a Docker (or Singularity) container\n", + "* `container` group access for the JSC systems as described [here](https://apps.fz-juelich.de/jsc/hps/juwels/container-runtime.html#getting-access) in the docs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check that the Singularity container runtime is available via the JupyterLab environment," + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "singularity version 3.6.4-1.el8\n" + ] + } + ], + "source": [ + "singularity --version" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Specify the filesystem location that stores the Singularity container image," + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "IMAGE_TARGET_DIR=/p/project/cesmtst/hoeflich1/jupyter-base-notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Optional, if you already have a Singularity container image available at the above location: Convert a containerized Python environment (e.g. the Jupyter `base-notebook` that is [available via Dockerhub](https://hub.docker.com/r/jupyter/base-notebook)) into a Singularity container image to be used as an example here," + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "mkdir -p ${IMAGE_TARGET_DIR}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that pulling and converting the Dockerhub image will take a bit of time," + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "singularity pull ${IMAGE_TARGET_DIR}/jupyter-base-notebook.sif docker://jupyter/base-notebook &> singularity.log" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO: Converting OCI blobs to SIF format\n", + "INFO: Starting build...\n", + "Getting image source signatures\n", + "Copying blob sha256:da7391352a9bb76b292a568c066aa4c3cbae8d494e6a3c68e3c596d34f7c75f8\n", + "Copying blob sha256:14428a6d4bcdba49a64127900a0691fb00a3f329aced25eb77e3b65646638f8d\n", + "Copying blob sha256:2c2d948710f21ad82dce71743b1654b45acb5c059cf5c19da491582cef6f2601\n", + "Copying blob sha256:e3cbfeece0aec396b6793a798ed1b2aed3ef8f8693cc9b3036df537c1f8e34a1\n", + "Copying blob sha256:48bd2a353bd8ed1ad4b841de108ae42bccecc44b3f05c3fcada8a2a6f5fa09cf\n", + "Copying blob sha256:235d93b8ccf12e8378784dc15c5bd0cb08ff128d61b856d32026c5a533ac3c89\n", + "Copying blob sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1\n", + "Copying blob sha256:b6c06056c45bc1da74604fcf368b02794fe4e36dcae881f4c6b4fa32b37a1385\n", + "Copying blob sha256:60918bcbe6d44988e4e48db436996106cc7569a4b880488be9cac90ea6883ae0\n", + "Copying blob sha256:762f9ebe4ddc05e56e33f7aba2cdd1be62f747ecd9c8f9eadcb379debf3ebe06\n", + "Copying blob sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1\n", + "Copying blob sha256:1df9d491a0390ecc3f9fac4484c92b2a5f71a79450017f2fca1849f2d6e7f949\n", + "Copying blob sha256:be84c8c720e3c53037ac2c5cbc53cf9a2a674503b2c995da1351e5560f60cc12\n", + "Copying blob sha256:28807e96859dc8c00c96255dfa51a0822380638a092803e7143473d1870970fb\n", + "Copying blob sha256:bcdaf848f29a8bf0efc18a5883dc65a4a7a6b2c6cf4094e5115188ed22165a00\n", + "Copying blob sha256:49777cff52f155a9ba35e58102ecec7029dddf52aa4947f2cffbd1af12848e81\n", + "Copying blob sha256:7fb3bffa2e730b052c0c7aabd715303cc5830a05b992f2d3d70afeffa0a9ed4f\n", + "Copying blob sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1\n", + "Copying config sha256:79f074439b14ae0634f2f217e5debc159c4e8c3a9ff2e0119e4dc88f9c7e21a5\n", + "Writing manifest to image destination\n", + "Storing signatures\n", + "2021/01/19 11:59:33 info unpack layer: sha256:da7391352a9bb76b292a568c066aa4c3cbae8d494e6a3c68e3c596d34f7c75f8\n", + "2021/01/19 11:59:34 info unpack layer: sha256:14428a6d4bcdba49a64127900a0691fb00a3f329aced25eb77e3b65646638f8d\n", + "2021/01/19 11:59:34 info unpack layer: sha256:2c2d948710f21ad82dce71743b1654b45acb5c059cf5c19da491582cef6f2601\n", + "2021/01/19 11:59:34 info unpack layer: sha256:e3cbfeece0aec396b6793a798ed1b2aed3ef8f8693cc9b3036df537c1f8e34a1\n", + "2021/01/19 11:59:34 info unpack layer: sha256:48bd2a353bd8ed1ad4b841de108ae42bccecc44b3f05c3fcada8a2a6f5fa09cf\n", + "2021/01/19 11:59:34 info unpack layer: sha256:235d93b8ccf12e8378784dc15c5bd0cb08ff128d61b856d32026c5a533ac3c89\n", + "2021/01/19 11:59:34 info unpack layer: sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1\n", + "2021/01/19 11:59:34 info unpack layer: sha256:b6c06056c45bc1da74604fcf368b02794fe4e36dcae881f4c6b4fa32b37a1385\n", + "2021/01/19 11:59:34 info unpack layer: sha256:60918bcbe6d44988e4e48db436996106cc7569a4b880488be9cac90ea6883ae0\n", + "2021/01/19 11:59:34 info unpack layer: sha256:762f9ebe4ddc05e56e33f7aba2cdd1be62f747ecd9c8f9eadcb379debf3ebe06\n", + "2021/01/19 11:59:34 info unpack layer: sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1\n", + "2021/01/19 11:59:34 info unpack layer: sha256:1df9d491a0390ecc3f9fac4484c92b2a5f71a79450017f2fca1849f2d6e7f949\n", + "2021/01/19 11:59:36 info unpack layer: sha256:be84c8c720e3c53037ac2c5cbc53cf9a2a674503b2c995da1351e5560f60cc12\n", + "2021/01/19 11:59:40 info unpack layer: sha256:28807e96859dc8c00c96255dfa51a0822380638a092803e7143473d1870970fb\n", + "2021/01/19 11:59:40 info unpack layer: sha256:bcdaf848f29a8bf0efc18a5883dc65a4a7a6b2c6cf4094e5115188ed22165a00\n", + "2021/01/19 11:59:40 info unpack layer: sha256:49777cff52f155a9ba35e58102ecec7029dddf52aa4947f2cffbd1af12848e81\n", + "2021/01/19 11:59:40 info unpack layer: sha256:7fb3bffa2e730b052c0c7aabd715303cc5830a05b992f2d3d70afeffa0a9ed4f\n", + "2021/01/19 11:59:40 info unpack layer: sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1\n", + "INFO: Creating SIF file...\n" + ] + } + ], + "source": [ + "cat singularity.log | grep -v warn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check that the Singularity image is available," + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "total 177M\n", + "drwxr-sr-x 2 hoeflich1 cesmtst 4.0K Jan 19 11:59 .\n", + "drwxr-sr-x 5 hoeflich1 cesmtst 4.0K Jan 19 11:59 ..\n", + "-rwxr-xr-x 1 hoeflich1 cesmtst 183M Jan 19 11:59 jupyter-base-notebook.sif\n" + ] + } + ], + "source": [ + "ls -lah ${IMAGE_TARGET_DIR}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, setup a Jupyter kernel specification with the `install-jupyter-kernel.sh` script from this repository (which basically writes a `kernel.json` file to the home directory location that Jupyter expects for user-specific kernels)," + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "KERNEL_DISPLAY_NAME=Singularity-Python # don't use whitespaces here!\n", + "SINGULARITY_IMAGE=${IMAGE_TARGET_DIR}/jupyter-base-notebook.sif" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Link to [install-singularity-jupyter-kernel.sh](https://raw.githubusercontent.com/FZJ-JSC/jupyter-jsc-notebooks/documentation/03-HowTos/details/install-singularity-jupyter-kernel.sh)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "./install-singularity-jupyter-kernel.sh ${KERNEL_DISPLAY_NAME} ${SINGULARITY_IMAGE}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check that the Jupyter kernel specification was written," + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"argv\": [\n", + " \"singularity\",\n", + " \"exec\",\n", + " \"--cleanenv\",\n", + " \"/p/project/cesmtst/hoeflich1/jupyter-base-notebook/jupyter-base-notebook.sif\",\n", + " \"python\",\n", + " \"-m\",\n", + " \"ipykernel\",\n", + " \"-f\",\n", + " \"{connection_file}\"\n", + " ],\n", + " \"language\": \"python\",\n", + " \"display_name\": \"Singularity-Python\"\n", + "}\n" + ] + } + ], + "source": [ + "cat ${HOME}/.local/share/jupyter/kernels/${KERNEL_DISPLAY_NAME}/kernel.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And that the above Singularity-Python kernel is visible by the Jupyter server," + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Available kernels:\n", + " singularity-python /p/home/jusers/hoeflich1/juwels/.local/share/jupyter/kernels/Singularity-Python\n", + " ruby /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-Ruby/2.6.3-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/ruby\n", + " ir35 /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-R/3.5.3-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/ir35\n", + " pyquantum-1.0 /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-PyQuantum/1.0-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/pyquantum-1.0\n", + " pyparaview-5.8 /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-PyParaView/5.8.0-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/pyparaview-5.8\n", + " octave /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-Octave/5.1.0-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/octave\n", + " julia-1.4 /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-Julia/1.4.2-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/julia-1.4\n", + " javascript /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-JavaScript/5.2.0-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/javascript\n", + " cling-cpp17 /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-Cling/0.6-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/cling-cpp17\n", + " bash /p/software/juwels/stages/Devel-2019a/software/JupyterKernel-Bash/0.7.1-gcccoremkl-8.3.0-2019.3.199-2019a.2.4/share/jupyter/kernels/bash\n", + " python3 /p/software/juwels/stages/Devel-2019a/software/Jupyter/2019a.2.4-gcccoremkl-8.3.0-2019.3.199-Python-3.6.8/share/jupyter/kernels/python3\n" + ] + } + ], + "source": [ + "jupyter kernelspec list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If so, you should be able to choose and connect to the containerized Python kernel from the drop down menu and/or the kernel launcher tab (a reload of the JupyterLab web page might be necessary)." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Bash", + "language": "bash", + "name": "bash" + }, + "language_info": { + "codemirror_mode": "shell", + "file_extension": ".sh", + "mimetype": "text/x-sh", + "name": "bash" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/users/jupyterlab/4.3/kernels_hpc_venv.ipynb b/docs/users/jupyterlab/4.3/kernels_hpc_venv.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..b35f18dcf8c2c7d02d37d7f87d0f6500c6221f33 --- /dev/null +++ b/docs/users/jupyterlab/4.3/kernels_hpc_venv.ipynb @@ -0,0 +1,449 @@ +{ + "cells": [ + { + "attachments": { + "9f53dcb1-00d6-4245-955a-b527f1540865.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": { + "toc-hr-collapsed": false + }, + "source": [ + "\n", + "<h5 style=\"text-align: right\">Author: <a href=\"mailto:j.goebbert@fz-juelich.de?subject=Jupyter-JSC%20documentation\">Jens Henrik Göbbert</a></h5> \n", + "<h5><a href=\"../index.ipynb\">Index</a></h5>\n", + "<h1 style=\"text-align: center\">Create your own Jupyter Kernel</h1> " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "toc-hr-collapsed": false + }, + "source": [ + "Often the standard kernel do not provide all features you need for your work. This might be that certain modules are not loaded or packages are not installed. \n", + "With your own kernel you can overcome that problem easily and define your own environment, in which you work.\n", + "\n", + "This notebook shows you how you can build your own kernel for a **python environment**.\n", + "\n", + "<div class=\"alert alert-block alert-info\">\n", + "<b>Attention:</b>\n", + "This notebook is meant to run out of a JupyterLab on JSC's HPC systems.</br>\n", + "</div>\n", + "\n", + "-------------------------" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Building your own Jupyter kernel is a three step process\n", + "1. Create/Pimp new virtual Python environment\n", + " * venv\n", + "2. Create/Edit launch script for the Jupyter kernel\n", + " * kernel.sh\n", + "3. Create/Edit Jupyter kernel configuration\n", + " * kernel.json" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Settings" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Set the kernel name\n", + " - must be lower case\n", + " - change if you like" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# INPUT NEEDED:\n", + "KERNEL_NAME=${USER}_kernel\n", + "\n", + "export KERNEL_NAME=$(echo \"${KERNEL_NAME}\" | awk '{print tolower($0)}')\n", + "echo ${KERNEL_NAME} # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Set the kernel directory\n", + " - check that the kernel name is unique\n", + " - print the location of the new kernel" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# define KERNEL_SPECS_DIR\n", + "export KERNEL_SPECS_PREFIX=${HOME}/.local\n", + "if [ ! -d \"$KERNEL_SPECS_PREFIX\" ]; then\n", + " echo \"ERROR: please create directory $KERNEL_SPECS_PREFIX\"\n", + "fi\n", + "export KERNEL_SPECS_DIR=${KERNEL_SPECS_PREFIX}/share/jupyter/kernels\n", + "\n", + "# check if kernel name is unique\n", + "if [ -d \"${KERNEL_SPECS_DIR}/${KERNEL_NAME}\" ]; then\n", + " echo \"ERROR: Kernel already exists in ${KERNEL_SPECS_DIR}/${KERNEL_NAME}\"\n", + " echo \" Rename kernel name or remove directory.\"\n", + "fi\n", + "\n", + "# print the location of the new kernel\n", + "echo ${KERNEL_SPECS_DIR}/${KERNEL_NAME} " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Set the kernel's virtual environment\n", + " - by default it is located at $PROJECT\n", + " - print the location of the new kernels virtual environment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# define KERNEL_VENVS_DIR\n", + "export KERNEL_VENVS_DIR=${PROJECT}/${USER}/jupyter/kernels\n", + "mkdir -p ${KERNEL_VENVS_DIR}\n", + "\n", + "# print the location of the new kernels virtual environment\n", + "echo ${KERNEL_VENVS_DIR}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Create/Pimp new virtual Python environment" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.1 - Load basic Python module" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "module purge\n", + "module load Stages/2025 # any stage can be used\n", + "module load GCC\n", + "module load Python # only Python is mandatory" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# get Python version\n", + "export PYV=$(python -c 'import sys; print(\".\".join(map(str, sys.version_info[:2])))')\n", + "echo $PYV" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.2 - Load extra modules you need for your kernel" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# module load <module you need>" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.3 - Create and activate a virtual environment for the kernel \n", + "and ensure python packages installed in the virtual environment are always prefered" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "export VIRTUAL_ENV=${KERNEL_VENVS_DIR}/${KERNEL_NAME}\n", + "if [ -d \"${VIRTUAL_ENV}\" ]; then\n", + " echo \"ERROR: Directory for virtual environment already ${VIRTUAL_ENV}\"\n", + " echo \" Rename kernel name or remove directory.\"\n", + "else\n", + " python -m venv --system-site-packages ${VIRTUAL_ENV}\n", + " source ${VIRTUAL_ENV}/bin/activate\n", + " export PYTHONPATH=${VIRTUAL_ENV}/lib/python${PYV}/site-packages:${PYTHONPATH}\n", + " echo ${VIRTUAL_ENV} # double check\n", + "fi" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.4 - Install Python libraries required for communication with Jupyter" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "which pip\n", + "if [ -z \"${VIRTUAL_ENV}\" ]; then\n", + " echo \"ERROR: Virtual environment not successfully initialized.\"\n", + "else\n", + " pip install ipykernel\n", + "fi" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 1.5 - Install whatever else you need in your Python virtual environment (using pip)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#pip install <python-package you need>" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Create/Edit launch script for the Jupyter kernel" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 2.1 - Create launch script, which loads your Python virtual environment and starts the ipykernel process inside:\n", + "\n", + "<div class=\"alert alert-block alert-info\">\n", + "<b>Attention:</b>\n", + "You MUST load the exactly the same modules as you did above for your virtual Python environment.\n", + "</div>" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "echo '#!/bin/bash'\"\n", + "\n", + "# Load basic Python module\n", + "module purge\n", + "module load Stages/2025\n", + "module load GCC\n", + "module load Python\n", + "\n", + "# Load extra modules you need for your kernel (as you did in step 1.2)\n", + "#module load <module you need>\n", + "\n", + "# Activate your Python virtual environment\n", + "source ${VIRTUAL_ENV}/bin/activate\n", + " \n", + "# Ensure python packages installed in the virtual environment are always prefered\n", + "export PYTHONPATH=${VIRTUAL_ENV}/lib/python${PYV}/site-packages:\"'${PYTHONPATH}'\"\n", + " \n", + "exec python -m ipykernel \"'$@' > ${VIRTUAL_ENV}/kernel.sh\n", + "chmod +x ${VIRTUAL_ENV}/kernel.sh\n", + "\n", + "cat ${VIRTUAL_ENV}/kernel.sh # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Create/Edit Jupyter kernel configuration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.1 - Create Jupyter kernel configuration directory and files" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "python -m ipykernel install --name=${KERNEL_NAME} --prefix ${VIRTUAL_ENV}\n", + "export VIRTUAL_ENV_KERNELS=${VIRTUAL_ENV}/share/jupyter/kernels" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.2 - Adjust kernel.json file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mv ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME}/kernel.json ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME}/kernel.json.orig\n", + "\n", + "echo '{\n", + " \"argv\": [\n", + " \"'${KERNEL_VENVS_DIR}/${KERNEL_NAME}/kernel.sh'\",\n", + " \"-m\",\n", + " \"ipykernel_launcher\",\n", + " \"-f\",\n", + " \"{connection_file}\"\n", + " ],\n", + " \"display_name\": \"'${KERNEL_NAME}'\",\n", + " \"language\": \"python\",\n", + " \"metadata\": {\n", + " \"debugger\": true\n", + " }\n", + "}' > ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME}/kernel.json\n", + "\n", + "cat ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME}/kernel.json # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.3 - Create link to kernel specs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mkdir -p ${KERNEL_SPECS_DIR}\n", + "cd ${KERNEL_SPECS_DIR}\n", + "ln -s ${VIRTUAL_ENV_KERNELS}/${KERNEL_NAME} .\n", + "\n", + "echo -e \"\\n\\nThe new kernel '${KERNEL_NAME}' was added to your kernels in '${KERNEL_SPECS_DIR}/'\\n\"\n", + "ls ${KERNEL_SPECS_DIR} # double check" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 3.4 - Use the kernel\n", + "- You can select the new kernel in the top right corner of your notebook or from JupyterLab's Launchpad\n", + "- The kernel icon will be added to your launcher, after a while by JupyterLab automatically or once you've restarted the JupyterLab" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Cleanup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "deactivate" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Bash", + "language": "bash", + "name": "bash" + }, + "language_info": { + "codemirror_mode": "shell", + "file_extension": ".sh", + "mimetype": "text/x-sh", + "name": "bash" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/mkdocs.yml b/mkdocs.yml index 94baf604158ecace118625d0c1d45588d0134c90..f884f32776401f8f9541290f9bac53ef69630032 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -58,6 +58,7 @@ nav: - 2-Factor authentication: 2fa.md - Available Resources and Tools: features.md - For Users: + - JupyterLab 4.3: users/jupyterlab/4.3/index.md - JupyterLab 4.2: users/jupyterlab/4.2/index.md - Custom Docker Images: users/jupyterlab/customdockerimage/index.md - Repo2Docker ( Binder ): users/jupyterlab/repo2docker/index.md