From 2ff9d8a922a9a1c3373cd333751c4732683649ac Mon Sep 17 00:00:00 2001 From: James Gebbie-Rayet Date: Tue, 15 Sep 2026 16:09:32 +0100 Subject: [PATCH] fix the nglview mismatch error in a graceful way --- docker/Dockerfile | 13 +++++++++++-- docker/fix-nglview.sh | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100755 docker/fix-nglview.sh diff --git a/docker/Dockerfile b/docker/Dockerfile index fff75e7..e1d3308 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -9,8 +9,17 @@ USER $NB_USER WORKDIR $HOME # Install workshop deps -RUN mamba install matplotlib numpy nglview ipywidgets -y -RUN pip install mdtraj mdplus +RUN conda install -y -c conda-forge \ + matplotlib=3.11.1 \ + numpy=2.5.3 \ + nglview=4.0.1 \ + ipywidgets=8.1.9 +RUN pip install --no-cache-dir \ + mdtraj==1.11.1 + mdplus==0.1.2 + +COPY docker/fix-nglview.sh /tmp/fix-nglview.sh +RUN bash /tmp/fix-nglview.sh # Get workshop files and move them to jovyan directory. COPY --chown=1000:100 . . diff --git a/docker/fix-nglview.sh b/docker/fix-nglview.sh new file mode 100755 index 0000000..9fdd518 --- /dev/null +++ b/docker/fix-nglview.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Locate nglview's Python frontend file +NGLVIEW_DIR=$(python -c "import nglview, os; print(os.path.dirname(nglview.__file__))") +FRONTEND_FILE="$NGLVIEW_DIR/_frontend.py" + +if [[ ! -f "$FRONTEND_FILE" ]]; then + echo "nglview _frontend.py not found, skipping patch" >&2 + exit 0 +fi + +# Locate the installed labextension's package.json by searching +# every labextensions directory Jupyter knows about (handles conda's +# $CONDA_PREFIX/share/jupyter/labextensions layout automatically) +LABEXT_PKG=$(python -c " +from jupyter_core.paths import jupyter_path +import os, sys +for d in jupyter_path('labextensions'): + candidate = os.path.join(d, 'nglview-js-widgets', 'package.json') + if os.path.isfile(candidate): + print(candidate) + sys.exit(0) +sys.exit(1) +") || { echo "nglview-js-widgets labextension not found, skipping patch" >&2; exit 0; } + +PY_VERSION=$(python -c "import re; print(re.search(r\"__frontend_version__ = '([^']+)'\", open('$FRONTEND_FILE').read()).group(1))") +JS_VERSION=$(python -c "import json; print(json.load(open('$LABEXT_PKG'))['version'])") + +# If there is a version mismatch then make them the same python side. +if [[ "$PY_VERSION" != "$JS_VERSION" ]]; then + echo "nglview mismatch: python=$PY_VERSION js=$JS_VERSION (found at $LABEXT_PKG) -- patching" + sed -i "s/__frontend_version__ = '$PY_VERSION'/__frontend_version__ = '$JS_VERSION'/" "$FRONTEND_FILE" +else + echo "nglview versions already match ($PY_VERSION), skipping patch" +fi