DEV Community

Cover image for El administrador de entornos virtuales que NO conoces: Pipenv
Eduardo Zepeda
Eduardo Zepeda

Posted on • Originally published at coffeebytes.dev

El administrador de entornos virtuales que NO conoces: Pipenv

Hace rato que quería escribir esta entrada. Desde que empecé a usar Python uso virtualenv y pip para manejar los entornos virtuales. Pero al leer Django for Professionals me enteré de que existía una herramienta mejor que pip y virtualenv, llamada Pipenv (no se complicaron mucho con el nombre). Pipenv tiene características que la hacen mucho más robusta y sencilla de utilizar que virtualenv. En este tutorial de Pipenv paso a paso, te voy a explicar la instalación, uso, manejo de archivos y comandos básicos de esta herramienta.

Primero, si ya has oído hablar de los entornos virtuales pero no sabes para que sirven dale una leída a esta entrada. Por otro lado, si el nombre de virtualenv te suena medio esotérico dale una revisada a esta entrada y te lo explico.

Pipenv vs virtualenv

Seguramente ya sabes que pip es usado para manejar paquetes, pero generalmente deseamos tener los paquetes de cada una de nuestras aplicaciones aislados del resto del sistema, por lo que normalmente lo combinamos con virtualenv.

Pip y virtualenv se usan en conjunto para mantener las dependencias de un entorno virtual, pero pip puede llegar a producir entornos diferentes, incluso con un mismo archivo requirements.txt, esto es algo que queremos evitar. El creador de pipenv diseño su herramienta intentando resolver esa problemática.

Pipenv se encarga de unir a pip y a virtualenv en una sola herramienta, además de asegurarse de que el archivo donde se listan las dependencias que se generan produzca exactamente la misma configuración de paquetes, pipenv también permite cargar archivos variables de entorno directamente a partir de archivos .env que se encuentren en la carpeta de trabajo donde nos encontremos.

Instalación y uso de pipenv

Si estás en Debian o alguna distribución derivada (como Ubuntu) puedes probar suerte intentando instalarlo directamente de los repositorios.

sudo apt install pipenv
Enter fullscreen mode Exit fullscreen mode

Si no se encuentra en los repositorios también podemos hacer uso de pip, que ya viene instalado en la mayoría de las distribuciones.

sudo pip install pipenv
Enter fullscreen mode Exit fullscreen mode

Una vez instalado podemos empezar a instalar paquetes usando la opción install, para este ejemplo probemos con una versión específica de Django.

pipenv install django===3.0.1
Enter fullscreen mode Exit fullscreen mode

Si hacemos un ls podremos notar que se nos crearon dos archivos Pipfile y Pipfile.lock.

ls
Pipfile  Pipfile.lock
Enter fullscreen mode Exit fullscreen mode

¿Qué tienen estos archivos? Te lo explico a continuación. Primero vamos con el archivo Pipfile.

Pipfile

Empecemos viendo el contenido del archivo Pipfile. Si tienes alguna dificultado con el uso de la linea de comandos te sugiero revisar las entradas donde hablo de los comandos más comunes de GNU/Linux.

cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
django = "===3.0.1"

[requires]
python_version = "3.7"
Enter fullscreen mode Exit fullscreen mode

Analizando el contenido apreciamos este archivo nos muestra varias categorias

  • source: la fuente de nuestros paquetes, con su nombre, url y si se usó encripción
  • dev-packages: los paquetes de desarrollo, en este momento se encuentra vacio
  • packages: los paquetes que hemos instalado y que se usarán en el proyecto
  • requires: la versión de Python requerida para el proyecto, se especifica automáticamente o puedes hacerlo tu mismo
pipenv install --dev pytest
Enter fullscreen mode Exit fullscreen mode

Si hacemos un cat nuevamente veremos que debajo de la sección [dev-packages] ya nos aparece pytest como una dependencia.

cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
pytest = "*"

[packages]
django = "===3.0.1"

[requires]
python_version = "3.7"
Enter fullscreen mode Exit fullscreen mode

Pipfile.lock

Ahora hagamos un cat a Pipfile.lock

cat Pipfile.lock
{
    "_meta": {
        "hash": {
            "sha256": "c2bf0d0008c675fc08df79a9cdb6b94773be0defa60d2c5b8aae0142358aa574"
        },
        "pipfile-spec": 6,
        "requires": {
            "python_version": "3.7"
        },
        "sources": [
            {
                "name": "pypi",
                "url": "https://pypi.org/simple",
                "verify_ssl": true
            }
        ]
    },
    "default": {
        "asgiref": {
            "hashes": [
                "sha256:7e51911ee147dd685c3c8b805c0ad0cb58d360987b56953878f8c06d2d1c6f1a",
                "sha256:9fc6fb5d39b8af147ba40765234fa822b39818b12cc80b35ad9b0cef3a476aed"
            ],
            "markers": "python_version >= '3.5'",
            "version": "==3.2.10"
        },
        "django": {
            "hashes": [
                "sha256:315b11ea265dd15348d47f2cbb044ef71da2018f6e582fed875c889758e6f844",
                "sha256:b61295749be7e1c42467c55bcabdaee9fbe9496fdf9ed2e22cef44d9de2ff953"
            ],
            "index": "pypi",
            "version": "===3.0.1"
        },
...
Enter fullscreen mode Exit fullscreen mode

El archivo puede parecer muy apantallante, pero son únicamente los hashes de los paquetes que instalamos, así como sus dependencias, de esta manera nos aseguramos de que las versiones que instalamos sean las correctas y además nos permitirá obtener exactamente la misma configuración de paquetes si tomamos estos archivos y los llevamos a otra computadora.

¿Cómo visualizar las dependencias de manera gráfica?

Si ahora usamos el comando pipenv graph nos generará una representación detallada y visualmente amigable de las dependencias que tenemos instaladas

pipenv graph
Django==3.0.1
 - asgiref [required: ~=3.2, installed: 3.2.10]
 - pytz [required: Any, installed: 2020.1]
 - sqlparse [required: >=0.2.2, installed: 0.3.1]
pytest==5.4.3
 - attrs [required: >=17.4.0, installed: 19.3.0]
 - importlib-metadata [required: >=0.12, installed: 1.7.0]
 - zipp [required: >=0.5, installed: 3.1.0]
 - more-itertools [required: >=4.0.0, installed: 8.4.0]
 - packaging [required: Any, installed: 20.4]
 - pyparsing [required: >=2.0.2, installed: 2.4.7]
 - six [required: Any, installed: 1.15.0]
 - pluggy [required: >=0.12,<1.0, installed: 0.13.1]
 - importlib-metadata [required: >=0.12, installed: 1.7.0]
 - zipp [required: >=0.5, installed: 3.1.0]
 - py [required: >=1.5.0, installed: 1.9.0]
 - wcwidth [required: Any, installed: 0.2.5]
Enter fullscreen mode Exit fullscreen mode

Generar un archivo Pipfile.lock

También podemos generar un archivo Pipfile.lock a partir de un archivo Pipfile. Borremos el archivo Pipfile.lock y generemos uno nuevo

rm Pipfile.lock
Enter fullscreen mode Exit fullscreen mode

Ahora ejecutemos el comando pipenv lock

pipenv lock
Locking [dev-packages] dependencies…
Building requirements...
Resolving dependencies...
✔ Success! 
Locking [packages] dependencies…
Building requirements...
Resolving dependencies...
✔ Success! 
Updated Pipfile.lock (88888)!
Enter fullscreen mode Exit fullscreen mode

Al terminar el proceso tendremos nuevamente nuestro archivo Pipfile.lock en la misma carpeta

Encontrar un entorno virtual con pipenv

Todo bien hasta este momento, pero aún no estamos dentro de nuestro entorno virtual, es más, solamente tenemos los archivos Pipfile y Pipfile.lock en nuestra carpeta actual. ¿Y el entorno virtual? Bueno, pipenv coloca el entorno virtual en otra ubicación, para averiguarla podemos usar la opción --venv

pipenv --venv
/home/usuario/.local/share/virtualenvs/proyecto-HHqROqC2
Enter fullscreen mode Exit fullscreen mode

Y ahora, en lugar de localizar el archivo activate manualmente en la ruta anterior, como hacíamos con virtualenv, podemos activar el entorno virtual usando el comando pipenv shell y esto se hará por nosotros automáticamente

pipenv shell
Enter fullscreen mode Exit fullscreen mode

De igual manera que con virtualenv podemos apreciar que el prompt cambiará, indicándonos que estamos dentro del entorno virtual

Variables de entorno con Pipenv

Una de las características que hacen diferente a pipenv es que te permite cargar variables de entorno directamente a partir de un archivo .env cuando entramos en un entorno virtual. Salgamos del entorno virtual un momento para crear el archivo y cargar variables de entorno.

exit
Enter fullscreen mode Exit fullscreen mode

Ahora que el prompt regresó a la normalidad, crearemos un archivo .env con variables de entorno. Lo haré en un solo paso usando el comando echo y redirigiendo el resultado al archivo, pero si te sientes más cómodo usando el comando touch y luego abriéndolo para agregar el contenido también puedes hacerlo y es correcto.

echo "SPAM=eggs" > .env
Enter fullscreen mode Exit fullscreen mode

Si hacemos un ls podremos ver que ahora tenemos nuestro archivo .env en la misma carpeta que están Pipfile y Pipfile.lock

ls -a
.  ..  .env  Pipfile  Pipfile.lock
Enter fullscreen mode Exit fullscreen mode

Ahora volvamos a cargar nuestro entorno virtual

pipenv shell
Loading .env environment variables…
Launching subshell in virtual environment…
 . /home/usuario/.local/share/virtualenvs/proyecto-HHqROqC2/bin/activate
Enter fullscreen mode Exit fullscreen mode

El prompt cambiará nuevamente, y, si ejecutamos el comando printenv podemos ver que nuestra variable de entorno se agregó perfectamente.

printenv
...
SPAM=eggs
...
Enter fullscreen mode Exit fullscreen mode

Desinstalar paquetes en pipenv

Para desinstalar paquetes usaremos el comando pipenv uninstall y el nombre del paquete.

pipenv uninstall pytest
Uninstalling pytest…
Found existing installation: pytest 5.4.3
Uninstalling pytest-5.4.3:
 Successfully uninstalled pytest-5.4.3

Removing pytest from Pipfile…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Building requirements...
Resolving dependencies...
✔ Success! 
Updated Pipfile.lock (3f348b)!
Enter fullscreen mode Exit fullscreen mode

Si queremos desinstalar todos los paquetes y dejar nuestro entorno como nuevo podemos usar la opción --all en lugar de especificar un nombre de paquete. Esto borrará todos los archivos del entorno virtual pero dejará el Pipfile completamente a salvo.

pipenv uninstall --all
Un-installing all [dev-packages] and [packages]…
Found 13 installed package(s), purging…
...
Environment now purged and fresh!
Enter fullscreen mode Exit fullscreen mode

Si usamos la opción --all-dev eliminará todas las dependencias de desarrollo, tanto como del entorno virtual como de nuestro Pipfile

pipenv uninstall --all-dev
Un-installing [dev-packages]…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Building requirements...
Resolving dependencies...
✔ Success! 
Updated Pipfile.lock (65a03c)!
Enter fullscreen mode Exit fullscreen mode

Ejecutar comandos en entorno virtual con pipenv

También podemos ejecutar comandos directamente en el entorno virtual sin estar dentro. Salte del entorno virtual si estás dentro y asegurate de que el prompt haya regresado a la normalidad antes de ejecutar el siguiente comando.

pipenv run pip install requests
Loading .env environment variables…
Collecting requests
 Downloading requests-2.24.0-py2.py3-none-any.whl (61 kB)
 |████████████████████████████████| 61 kB 53 kB/s 
Collecting idna<3,>=2.5
 Downloading idna-2.10-py2.py3-none-any.whl (58 kB)
 |████████████████████████████████| 58 kB 641 kB/s 
Collecting chardet<4,>=3.0.2
 Using cached chardet-3.0.4-py2.py3-none-any.whl (133 kB)
Collecting certifi>=2017.4.17
 Downloading certifi-2020.6.20-py2.py3-none-any.whl (156 kB)
 |████████████████████████████████| 156 kB 6.1 MB/s 
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
 Using cached urllib3-1.25.9-py2.py3-none-any.whl (126 kB)
Installing collected packages: idna, chardet, certifi, urllib3, requests
Successfully installed certifi-2020.6.20 chardet-3.0.4 idna-2.10 requests-2.24.0 urllib3-1.25.9
Enter fullscreen mode Exit fullscreen mode

El comando anterior nos dejó con el paquete requests y sus dependencias instaladas en nuestro entorno virtual, sin embargo el archivo Pipfile y Pipfile.lock no se actualizaron. Para borrar todos aquellos paquetes instalados que no se encuentren en los dos archivos anteriores existe pipenv clean.

Limpiar nuestro entorno virtual en pipenv

También podemos limpiar nuestro entorno virtual de todos aquellos paquetes que no estén especificados dentro de nuestro archivo Pipfile.lock usando clean.

pipenv clean
Uninstalling urllib3…
Uninstalling idna…
Uninstalling requests…
Uninstalling chardet…
Uninstalling certifi…
Enter fullscreen mode Exit fullscreen mode

Listo, nuestro entorno no contiene ningún paquete instalado, sin embargo aún existe.

Borrar un entorno virtual en pipenv

Para borrar un entorno virtual usaremos la opción --rm seguida del comando pipenv. Nota que pipenv detectará el entorno virtual a remover extrayendo la información de la carpeta donde nos encontremos, por lo que asegúrate dos veces que estás en la carpeta correcta.

pipenv --rm
Removing virtualenv (/home/usuario/.local/share/virtualenvs/prueba-HHqROqC2)
Enter fullscreen mode Exit fullscreen mode

El entorno virtual ha quedado eliminado completamente.

Si quieres conocer más funciones de pipenv puedes visitar su documentación oficial.

Si te gustó esta entrada sígueme en Twitter, publico un tweet cada que tengo una nueva entrada. Además Twitteo frecuentemente información interesante sobre tecnología que puede servirte.

Top comments (2)

Collapse
 
javierperezmanzanaro profile image
Javier_Perez

Muy buen artículo. Muchas gracias. Muy util.

Tengo una duda, ¿sabes que me pasa, por favor?: trabajo en dos macs. He creado un entorno con pipenv y trabajo perfectamente con el pero hago una copia del entorno en un USB para trabajar con el otro mac y no hay forma de activarlo.

La hice usado virtualenv 'entorno' -p python3.10 para tener todo el entono en bajo una carpeta.

Uso Visual Studio Code.

¿sabes como puedo exportar un entorno?

Collapse
 
zeedu_dev profile image
Eduardo Zepeda

No sé si te entendí correctamente, pero no copies directamente el entorno virtual. Solo copia los pipfiles y pipfile.lock y corre pipenv install en la usb. Es mejor no exportar el entorno, sino solo guardar los Pipfiles y reinstalar todo nuevamente.