Terminals and ! commands in JupyterHub not using virtualenv Python

Hi all,

I’m running JupyterHub 3.1.1 in a Docker container on Kubernetes. My virtual environment is located at:

/usr/src/myproject/.venv/

My goal is that when a user opens a terminal inside Jupyterhub, python points to the venv, instead of the system Python (/usr/local/bin/python). Also, when executing shell commands in notebook cells using ! ..., I want them to use the venv Python.

Currently, terminals show:

user@<pod>:~$ which python
/usr/local/bin/python

I’ve tried setting the spawner environment:

import os

venv_bin = "/usr/src/myproject/.venv/bin"
c.Spawner.environment = {
    "PATH": f"{venv_bin}:{os.environ.get('PATH', '')}",
    "VIRTUAL_ENV": "/usr/src/myproject/.venv"
}

This does not affect terminal shells or ! commands.

I’ve read about c.LocalProcessSpawner.shell_cmd and profile scripts, but I’m not sure what the best practice is in JupyterHub 3.x to ensure all terminals and ! commands default to the virtual environment Python without hardcoding it in every user shell.

Any guidance or examples would be greatly appreciated.

Thanks!

Can you check if your c.Spawner.environment config is having any effect? e.g. setting “TESTVARIABLE”: “TESTVALUE”? It could be that the config isn’t being loaded, or is being overridden by some later config. Check the value of $VIRTUAL_ENV and $PATH.

For the most part, I would expect your config to work, so I expect something is getting a little wonky

If you want a virtualenv to be truly fully activated, including whatever setup scripts, you’re right that c.LocalProcessSpawner.shell_cmd could be part of it. For such things, I usually use the c.Spawner.cmd approach, where you write a shell script that does activation, etc. (maybe even bash -l), then always ends with exec jupyterhub-singleuser "$@":

#!/bin/bash -l
# ^login shell means source everything in profile.d, bash_profile, etc.

# activate the project env
source /usr/src/myproject/.venv/bin/activate

# finally, 'become' jupyterhub-singleuser
exec jupyterhub-singleuser "$@"
2 Likes