# Instalación y dependencias Ahora que sabes lidiar con módulos, necesitas aprender a instalarlos en tu propio sistema, porque es bastante tedioso que tengas que copiar el código de todas tus dependencias en la carpeta de tu proyecto. En la introducción no aseguramos de instalar con python la herramienta `pip`. Que sirve para instalar paquetes nuevos en el sistema de forma sencilla. ## Funcionamiento de `pip` `pip` es una herramienta extremadamente flexible, capaz de instalar módulos de python de diferentes fuentes: repositorios de git, carpetas de sistema o, la más interesante quizás de todas, el *Python Package Index* (*PyPI*)[^pypi]. [^pypi]: https://pypi.org/ `pip` buscará la descripción del paquete en la fuente que se le indique y, de esta descripción, obtendrá las dependencias necesarias y las indicaciones de cómo debe instalarlo. Una vez procesadas las normas, procederá a instalar el paquete en el directorio de sistema con todas las dependencias de éste para que funcione correctamente. Una vez instalado el paquete en el directorio de sistema está listo para ser importado. ### PyPI El *Python Package Index* o *PyPI* es un repositorio que contiene software programado en python. En él se listan miles de librerías creadas por programadores de python para que cualquiera pueda descargarlas e instalarlas. Más adelante veremos algunas de ellas y nos acostumbraremos a usarl PyPI como recurso. Ahora que sabes programar en python tú también puedes publicar tus proyectos ahí para que otras personas los usen para crear los suyos. ### Reglas de instalación: `setuptools` y `setup.py` Para que `pip` pueda hacer su trabajo correctamente hay que indicarle cómo debe hacerlo, ya que cada paquete es un mundo y tiene necesidades distintas. El módulo `setuptools` permite crear un conjunto de reglas comprensible por `pip` que facilita la distribución e instalación. Normalmente este conjunto de reglas suele almacenarse en un fichero de nombre `setup.py`. Como ejemplo de `setup.py` puedes ver el de la librería `BeautifulSoup4`[^bs4-setup] que se adjunta a continuación con ligeras alteraciones para que encaje en la página: [^bs4-setup]: https://www.crummy.com/software/BeautifulSoup/bs4/doc/ ``` {.python .numberLines} from setuptools import ( setup, find_packages, ) with open("README.md", "r") as fh: long_description = fh.read() setup( name="beautifulsoup4", # NOTE: We can't import __version__ from bs4 because bs4/__init__.py # is Python 2 code, and converting it to Python 3 means going through # this code to run 2to3. # So we have to specify it twice for the time being. version = '4.8.1', author="Leonard Richardson", author_email='leonardr@segfault.org', url="http://www.crummy.com/software/BeautifulSoup/bs4/", download_url = "http://www.crummy.com/software/BeautifulSoup/bs4/download/", description="Screen-scraping library", install_requires=["soupsieve>=1.2"], long_description=long_description, long_description_content_type="text/markdown", license="MIT", packages=find_packages(exclude=['tests*']), extras_require = { 'lxml' : [ 'lxml'], 'html5lib' : ['html5lib'], }, use_2to3 = True, classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 2.7", 'Programming Language :: Python :: 3', "Topic :: Text Processing :: Markup :: HTML", "Topic :: Text Processing :: Markup :: XML", "Topic :: Text Processing :: Markup :: SGML", "Topic :: Software Development :: Libraries :: Python Modules", ], ) ``` En el ejemplo se aprecia a la perfección el tipo de información que es necesario aportarle a `setuptools`. Dependiendo del proyecto, esta configuración puede ser más compleja o más sencilla, y tendrás que indagar a través de la configuración de `setuptools` para ajustar la herramienta a tu proyecto. ## Entornos virtuales y dependencias: `pipenv` La herramienta `pip` es interesante para instalar herramientas en el sistema pero tiene ciertas carencias. La primera, que no es capaz de resolver las dependencias a la hora de desinstalar paquetes, por lo que, si se instala un paquete que dependa de otro paquete, `pip` instalará todas las dependencias necesarias, pero por miedo a romper paquetes, no las desinstalará si se le pide desinstalar el paquete que las arrastró. Por otro lado, si quieres trabajar en proyectos de desarrollo, probablemente tengas que instalar sus dependencias. Si tienes varios proyectos en marcha simultáneamente o si tus sistema necesita de alguna herramienta escrita en python, es posible que tengas colisiones. Imagina que dos de los proyectos, por ejemplo, usan versiones diferentes de una de sus librerías. Si instalas sus dependencias usando `pip`, se mezclaran en tu sistema y no podrán coexistir. Además, cuando termines los proyectos o abandones su desarrollo, te interesará limpiar sus dependencias de tu sistema, cosa complicada si `pip` no gestiona la liberación de paquetes de forma correcta. Para evitar estos problemas y algún otro adicional, existen herramientas adicionales que alteran el comportamiento de `pip` y del propio python, creando lo que se conoce como *entornos virtuales* (*virtual environments*) que quedan aislados entre ellos y el sistema. El funcionamiento de los entornos virtuales es muy sencillo. Cuando se activan, crean un nuevo contexto en el que alteran las variables de entorno que describen dónde debe buscarse el intérprete de python, dónde busca éste los módulos y dónde instala `pip` los paquetes. Cuando se desactivan, se restaura el entorno por defecto. De este modo, cada entorno virtual queda perfectamente aislado de otros o incluso de la instalación del sistema, permitiéndote hasta tener diferentes versiones de python en tu sistema y que no colisionen entre ellas. Cuando has terminado con tu entorno virtual puedes borrarlo de forma segura sabiendo que no va a afectar a tu sistema y que va a llevarse todas las dependencias con él. Históricamente se han utilizado varias herramientas para esta labor, como `virtualenv`, que como era poco amigable se simplificaba con `virtualenv-wrapper` u otras. Hoy en día `pipenv` es la herramienta recomendada. `pipenv` es una combinación de `virtualenv` y `pip` creada para gestionar entornos virtuales y dependencias de desarrollo. Puedes considerarla un gestor de paquetes de desarrollo como `npm` en JavaScript, `composer` en PHP o cualquier otro que conozcas. Aporta la mayor parte de funcionalidades habituales como ficheros de dependencias, lockfiles etc. mientras que expone una interfaz de comandos sencilla y bien documentada. ### Instalación Para instalar pipenv, podemos usar `pip`, que instalamos en la introducción. En la shell de sistema ejecutando: ``` bash pip install pipenv ``` > NOTA: en función del sistema que utilices, puede que `pip` se llame > `pip3`. El funcionamiento es idéntico. ### Uso Una vez instalado `pipenv`, puedes usarlo en el directorio que desees para crear un conjunto de nuevas dependencias pidiéndole que instale un nuevo paquete lanzando la orden `pipenv install` en la shell de sistema. Para ejecutar módulos en el entorno virtual recién creado dispones de dos opciones: `pipenv shell` que prepara una shell de sistema en el entorno o `pipenv run` que ejecuta el comando que se le envíe en el entorno. Puedes seguir añadiendo dependencias al proyecto con `pipenv install` y eliminar las que no te gusten con `pipenv uninstall`. Además, dispones de muchas opciones adicionales que te animo que ojees ejecutando `pipenv --help`. ### Usar IDLE desde un entorno virtual Si utilizas entornos virtuales deberás preparar IDLE para verlos y que su REPL y su intérprete encuentren los paquetes del entorno virtual. Puedes lanzar IDLE desde el entorno virtual usando el siguiente truco en la shell de sistema: ``` bash pipenv run python -m idlelib.idle ``` Recordando el capítulo anterior y lo descrito en este, ese comando ejecuta `python -m idlelib.idle` en el entorno virtual en el que te encuentres. El comando, por su parte le pide a python que ejecute el módulo `idle` del paquete `idlelib`, que contiene el propio programa IDLE. Si trabajas con otros editores integrados de código tendrás que aprender a hacer que sus intérpretes busquen en el entorno virtual actual, pero casi todos los editores actuales soportarán esta opción de una forma u otra. ## Otras herramientas La realidad es que las herramientas propuestas no son las únicas que existen para estas tareas. Históricamente, python ha tenido otras herramientas con comportamientos similares a `pip`, como `easy_install` y otras con parecidas a `setuptools` como `distutils` y otras que asemejan a `pipenv`. Este capítulo trata únicamente las herramientas que se consideran las recomendadas en el momento en el que se está escribiendo[^recommended-tools], aunque los conceptos descritos son extrapolables, no sólo a otras herramientas sino también a otros lenguajes y entornos. [^recommended-tools]: Para un listado más extenso, visitar: ## Lo que has aprendido En este capítulo has aprendido lo necesario sobre las herramientas que rodean a python y su uso. De este modo, no te vas a sentir perdido en un maremágnum de nombres extraños y comandos cuando trabajes en proyectos que ya las usan. Más que convertirte en un experto de cómo trabajar con estas herramientas, cosa que te dará la práctica, este episodio te ha dado las referencias que necesitas para ir creciendo por tu cuenta en su uso, explicándote el interés de cada una de ellas. Te encontrarás, probablemente, proyectos que utilicen las herramientas de un modo peculiar, usen otras herramientas o hasta proyectos que no las usen correctamente. Este es un mundo complejo, y la historia de python no facilita la elección. Durante mucho tiempo la comunidad creó nuevas herramientas para suplir las carencias de otras y el ecosistema se complicó. A pesar de que hoy en día se recomiende el uso de unas herramientas sobre otras, no siempre fue así y muchos proyectos se han quedado obsoletos en este sentido. Para evitar atarte a las herramientas que aquí se muestran, se ha preferido darte una ligera noción, haciéndote recordar que las herramientas no son realmente lo importante, sino el conocimiento subyacente. Con la herramienta principal que has conocido en este apartado, `pipenv`, podrás instalar los paquetes que quieras de forma aislada y jugar con ellos todo lo que desees sin manchar tu sistema por lo que podrás adentrarte en los próximos capítulos sin miedo a estropear tu pulcra configuración inicial.