If I nix develop
on my mkShell
from this flake and run jupyter lab
,I will get an instance of jupyter lab which is aware of and able to load the bash-kernel
from the $out/share
of the bash-kernel
derivation.
{
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-linux" ];
perSystem = { config, self', inputs', pkgs, system, ... }: {
devShells.default = pkgs.mkShell {
buildInputs = let
python = pkgs.python3.withPackages (p: with p; [
jupyter
ipython
widgetsnbextension
bash-kernel
]);
in [
python
];
};
};
};
}
However, when I try to use it, the kernel loading crashes because jupyter is using a vanilla python interpreter without the correct paths set up. Anyone got an idea how this could be properly fixed?
[I 2025-06-08 15:14:07.245 ServerApp] Creating new notebook in
/nix/store/8w718rm43x7z73xhw9d6vh8s4snrq67h-python3-3.12.10/bin/python3.12: No module named bash_kernel
[I 2025-06-08 15:14:07.586 ServerApp] Kernel started: de2e1d8a-2cb7-4fc3-8a16-8c697b1ea24c
[I 2025-06-08 15:14:10.574 ServerApp] AsyncIOLoopKernelRestarter: restarting kernel (1/5), new random ports
/nix/store/8w718rm43x7z73xhw9d6vh8s4snrq67h-python3-3.12.10/bin/python3.12: No module named bash_kernel
[I 2025-06-08 15:14:13.588 ServerApp] AsyncIOLoopKernelRestarter: restarting kernel (2/5), new random ports
/nix/store/8w718rm43x7z73xhw9d6vh8s4snrq67h-python3-3.12.10/bin/python3.12: No module named bash_kernel
[I 2025-06-08 15:14:16.601 ServerApp] AsyncIOLoopKernelRestarter: restarting kernel (3/5), new random ports
/nix/store/8w718rm43x7z73xhw9d6vh8s4snrq67h-python3-3.12.10/bin/python3.12: No module named bash_kernel
1 Like
Worth noting that I can just run the Python from this shell, and import bash_kernel
user: matthew ~/tmp/minimal via 🐍 took 1m13s
❯ nix develop -L
user: matthew ~/tmp/minimal via 🐍 v3.12.10 via ❄️ impure (nix-shell-env)
❯ python
Python 3.12.10 (main, Apr 8 2025, 11:35:47) [GCC 14.2.1 20250322] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import bash_kernel
Ah interesting, I’ve just found that the kernel.json
found in $out/share
of the bash-kernel
derivation contains the path to the vanilla python interpreter without its own module
$ cat result/share/jupyter/kernels/bash/kernel.json
{"argv": ["/nix/store/2mab9iiwhcqwk75qwvp3zv0bvbiaq6cs-python3-3.13.3/bin/python3.13", "-m", "bash_kernel", "-f", "{connection_file}"], "codemirror_mode": "shell", "display_name": "Bash", "env": {"PS1": "$"}, "language": "bash"}
$ /nix/store/2mab9iiwhcqwk75qwvp3zv0bvbiaq6cs-python3-3.13.3/bin/python3.13 -m bash_kernel
/nix/store/2mab9iiwhcqwk75qwvp3zv0bvbiaq6cs-python3-3.13.3/bin/python3.13: No module named bash_kernel
Unfortunately it looks like we do actually re-implement the kernel.json files in Nix by hand instead of patching this behavior in some way, see nixpkgs/pkgs/applications/editors/jupyter-kernels/iruby/default.nix at ae91003958555b8b73c17e6536a302ff492c9d04 · NixOS/nixpkgs · GitHub
I couldn’t find any documentation on this jupyter-kernels
dir in nixpkgs.
According to its comments, you’re just supposed to nix run --impure --expr 'with import <nixpkgs> {}; jupyter.override { definitions.iruby = iruby.definition; }'
but if your kernel is hanging out in nixpkgs without having been packaged in this way, like the python3.pkgs.bash-kernel
is, then you don’t have something to pass to jupyter.override
Even though my example above will half-work, and be loaded by jupyter, just by having it on the path, which is a tiny patch away from working properly without needing to redundantly redefine the kernel.json in Nix code.
This is a workaround that does everything by hand, which I don’t think is great, but it works:
{
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ "x86_64-linux" "aarch64-linux" ];
perSystem = { config, self', inputs', pkgs, system, ... }: {
devShells.default = pkgs.mkShell {
buildInputs = [
(pkgs.jupyter.override {
definitions.bash-kernel = {
displayName = "Bash";
argv = [
"${(pkgs.python3.withPackages (p: [ p.bash-kernel ])).interpreter}"
"-m"
"bash_kernel"
"-f"
"{connection_file}"
];
logo32 = "${pkgs.python3.pkgs.bash-kernel}/share/jupyter/kernels/bash/logo-svg.svg";
logo64 = "${pkgs.python3.pkgs.bash-kernel}/share/jupyter/kernels/bash/logo-svg.svg";
};
})
];
};
};
};
}
1 Like