Usar entornos virtuales de Python con PIP en Jupyter desde Docker

Introducción

Para usar entornos virtuales de Python (venv o virtualenv) instalados con el gestor de paquetes PIP en el entorno de ejecución de código Jupyter debemos de usar los pasos que se indican a continuación. De esta forma tendremos las librerías cargadas independientemente entre los distintos Kernels de ejecución del sistema.

En una entrada anterior explicamos como instalar el entorno de ejecución de código Jupyter en Docker.


Acceso al sistema

Primero debemos de crear el entorno virtual en nuestro sistema, en donde tengamos Jupyter instalado. Podemos hacerlo de dos formas.

Acceso desde Docker

En nuestro caso disponemos de Jupyter ofrecido desde un contenedor de Docker, por lo que nos conectamos al Sistema Operativo de este a partir de su identificador.

# docker ps
c0fc212515f0 jupyter/minimal-notebook "tini -g -- start-..." 6 days ago Up 6 days 0.0.0.0:8888->8888/tcp tender_hopper

Nos conectamos al entorno a partir del Container ID, cámbialo por el tuyo:

docker exec -it c0fc212515f0 bash

Acceso desde la terminal de Jupyter

También podemos acceder al Sistema Operativo acediendo desde el terminal de la interfaz Web, ya que esta muestra el Prompt del propio sistema en donde se encuentra corriendo Jupyter.


Crear directorio para el entorno

Es buena práctica crear un directorio para los Notebooks que usaremos en este entorno virtual. Por ejemplo, vamos a crear un entorno para Redis, por lo que creamos el directorio:

jovyan@c0fc212515f0:~$ pwd
/home/jovyan
jovyan@c0fc212515f0:~$ ls
'Codigo Curso Python'
jovyan@c0fc212515f0:~$ mkdir Redis
jovyan@c0fc212515f0:~$ ls
'Codigo Curso Python' Redis

Y nos situamos en este:

jovyan@c0fc212515f0:~$ cd Redis/
jovyan@c0fc212515f0:~/Redis$ pwd
/home/jovyan/Redis

Crear y configurar el entorno virtual

Ahora creamos el entorno virtual. Si no disponemos del paquete necesario para crar estos entornos debemos de instalarlo:

pip install virtualenv

Creamos el entorno virtual, que en nuestro caso llamaremos .redis, por ejemplo, indicando la versión de Python que queremos que corra en este entorno. Usamos un punto al inicio del nombre del entorno para que este sea oculto y no se muestre en el listado de archivos y Notebooks del directorio en Jupyter:

python -m venv .redis

O con este otro comando si solo tenemos Python3 corriendo en nuestro sistema:

virtualenv .redis

Arrancamos el entorno virtual con el comando:

jovyan@c0fc212515f0:~/Redis$ . .redis/bin/activate

O con el comando:

jovyan@c0fc212515f0:~/Redis$ source .redis/bin/activate

Instalamos las librerías que precisemos, en nuestro caso instalaremos la librería redis ya que esta no está incluida en el entorno en estos momentos:

(.redis) jovyan@c0fc212515f0:~/Redis$ pip list
Package    Version
---------- -------
pip        20.0.2
setuptools 45.2.0
wheel      0.34.2

(.redis) jovyan@c0fc212515f0:~/Redis$ pip install redis
Collecting redis
  Using cached redis-3.4.1-py2.py3-none-any.whl (71 kB)
Installing collected packages: redis
Successfully installed redis-3.4.1

Ya la tendríamos instalada:

(.redis) jovyan@c0fc212515f0:~/Redis$ pip list
Package    Version
---------- -------
pip        20.0.2
redis      3.4.1
setuptools 45.2.0
wheel      0.34.2

Crear Kernel sobre el entorno virtual

Ahora debemos de crear un nuevo Kernel que contenga al entorno virtual creado. De esta forma cualquier Notebook que creemos seleccionando este podrá utilizar las librerías que tenga instaladas.

Instalar la librería ipykernel

Primero instalamos la librería ipykernel dentro del entorno virtual en el que nos encontremos. Esto tendremos que realizarlo en todos los Kernels que vayamos a crear.

pip install ipykernel

Creación del Kernel

Creamos el nuevo Kernel con el siguiente comando, indicando el nombre que queramos. En nuestro caso lo llamaremos Redis. Si todo ha ido bien se indicará un mensaje con el resultado de la instalación:

(.redis) jovyan@c0fc212515f0:~/Redis$ python -m ipykernel install --user --name=Redis
Installed kernelspec Redis in /home/jovyan/.local/share/jupyter/kernels/redis

En el directorio creado para la instalación tenemos un archivo kenel.json con los datos de configuración del nuevo Kernel:

(.redis) jovyan@c0fc212515f0:~/Redis$ cat /home/jovyan/.local/share/jupyter/kernels/redis/kernel.json
{
 "argv": [
  "/home/jovyan/Redis/.redis/bin/python",
  "-m",
  "ipykernel_launcher",
  "-f",
  "{connection_file}"
 ],
 "display_name": "Redis",
 "language": "python"
}

Este nuevo Kernel ya aparece en el sistema si recargamos la consola Web:


Usar el nuevo Kernel

Ahora podemos usar el nuevo Kernel con las librerías que este entorno virtual tuviera instaladas. Hagamos un ejemplo para ver esto de manera sencilla.

Si creamos un Notebook usando un Kernel distinto al creado e importamos la librería redis instalada en un apartado anterior nos debería de mostrar un error al ejecutar la línea (Shift + Enter):

Pero si por el contrario usamos el nuevo Kernel, la importación de la librería redis funcionará correctamente: Con esto confirmamos que podemos usar el entorno virtual a partir de la creación del Kernel.


Comandos de gestión para Kernels

Ya vimos anteriormente el comando necesario para la creación de Kernels, pero hagamos un breve resumen de comandos para la gestión de estos (creación/listado/eliminación).

Listar Kernels

Usamos el comando:

(.redis) jovyan@c0fc212515f0:~/Redis$ jupyter kernelspec list
Available kernels:
  python3    /home/jovyan/.local/share/jupyter/kernels/python3
  redis      /home/jovyan/.local/share/jupyter/kernels/redis

Crear Kernel

Para cear un Kernel nuevo ejecutamos el comando que vimos en una sección anterior:

(.redis) jovyan@c0fc212515f0:~/Redis$ python -m ipykernel install --user --name=Redis2
Installed kernelspec Redis in /home/jovyan/.local/share/jupyter/kernels/redis2

El nuevo Kernel ya figura en el listado:

(.redis) jovyan@c0fc212515f0:~/Redis$ jupyter kernelspec listAvailable kernels:
  python3    /home/jovyan/.local/share/jupyter/kernels/python3
  redis      /home/jovyan/.local/share/jupyter/kernels/redis
  redis2     /home/jovyan/.local/share/jupyter/kernels/redis2

Borrar Kernel

Para borrar un Kernel del listado de creados usamos el siguiente comando, confirmando que sí queremos borrarlo [y]:

(.redis) jovyan@c0fc212515f0:~/Redis$ jupyter kernelspec remove redis2
Kernel specs to remove:
  redis2                /home/jovyan/.local/share/jupyter/kernels/redis2
Remove 1 kernel specs [y/N]: y
[RemoveKernelSpec] Removed /home/jovyan/.local/share/jupyter/kernels/redis2

Este ya no figuraría en el listado:

(.redis) jovyan@c0fc212515f0:~/Redis$ jupyter kernelspec listAvailable kernels:
  python3    /home/jovyan/.local/share/jupyter/kernels/python3
  redis      /home/jovyan/.local/share/jupyter/kernels/redis

Enlaces de interés

Entornos virtuales en Jupyter > https://janakiev.com/blog/jupyter-virtual-envs/

Administrar Kernels > http://queirozf.com/entries/jupyter-kernels-how-to-add-change-remove