Un gestor de paquetes poético
En la mayoría de los artículos que he escrito en el blog los ejemplos de código que he mostrado siempre son gestionados por una tool llamada poetry, esta herramienta ha venido ganando terreno dentro del ecosistema de python, por ejemplo en el state python 2020 como se puede ver en la Figura 1 ya apareció en la lista de preferencias de algunos usuarios, también en proyectos públicos en github se pueden encontrar proyectos que lo usan, pero que es realmente poetry? qué beneficios ofrece? en este artículo responderemos estas preguntas
Que es poetry?
Su documentacion oficial lo define como un gestor de dependencias y un empaquetador de librerías python, si han desarrollado con python depronto han escuchado un poco del dependency hell (ver Figura 2) en donde el reto está en coordinar versiones de librerías, versiones de python y versiones de diferentes frameworks para instalar exactamente las versiones con las que el proyecto funciona buscando que durante el proceso no entre en conflicto con otros proyectos que usen las mismas dependencias pero con diferentes versiones... por tal motivo buscando diferentes soluciones me he encontrado con poetry, uno de los mayores beneficios de este gestor de dependencias es su archivo pyproject.toml este archivo es la clave de poetry, este contiene información de la metada del proyecto y de todas sus dependencias, si han trabajado con node y npm es el equivalente a package.json, pero adicionalmente poetry tiene su propio CLI este es una gran ventaja a largo plazo pues facilita entre muchas cosas acceso a diferentes configuraciones de manera rápida y sencilla, a lo largo del artículo analizaremos algunos comandos que podremos utilizar, sin embargo en su documentacion encontrarán toda la información
Para iniciar a trabajar con poetry tenemos 2 comandos claves, los 2 al final del dia nos inicializan el archivo pyproject.toml pero de diferente forma
- poetry init este primer comando nos inicializa un proyecto de manera interactiva como se ve en la Figura 3 y el resultado es un archivo pyproject.toml con la siguiente información
[tool.poetry]
name = "poetry-intro"
version = "0.1.0"
description = "Este es un ejemplo"
authors = ["jairo <me@jairoandres.com>"]
[tool.poetry.dependencies]
python = "^3.7"
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
- poetry new con este comando poetry genera un archivo de configuración, pero además genera una estructura de proyecto (ver Figura 4) lista para empezar a codificar, para este ejemplo usare el comando
poetry new myporyecto --name src
para que dentro del proyecto cree una carpeta llamada src donde estará todo el código python
Solamente Virtualenv y Pip
Generalmente cuando se trabaja con un stack en python se utilizan estas dos herramientas, de hecho por ejemplo el libro two scoops django las recomienda, y funcionan muy bien ademas que son muy prácticas y cumplen con el 12 twelve factor al tener las dependencias en un archivo manifiesto y usarlas aisladas del sistema principal, sin embargo esto genera algunos inconvenientes como se describieron aquí ya que pip es solo un instalador de paquetes y virtualenv un aislador, pero realmente aquí no se tiene un gestor de paquetes, al no tenerlo en mi caso un problema común que me sucedía al utilizar sólo estas dos herramientas se presenta a continuación:
Instalo cualquier librería, la mayoría de librerías tienen dependencias de otras librerías por lo tanto al instalar se instalan sus dependencias, por ejemplo utilizare flask
pip install flask
Al ejecutar este comando me instala además de flask sus dependencias
click==7.1.2
Flask==1.1.2
itsdangerous==1.1.0
Jinja2==2.11.3
MarkupSafe==1.1.1
Werkzeug==1.0.1
El problema viene cuando deseo desinstalar flask
pip uninstall flask
click==7.1.2
itsdangerous==1.1.0
Jinja2==2.11.3
MarkupSafe==1.1.1
Werkzeug==1.0.1
Lo pueden notar? no se desinstalaron las dependencias que tenía flask, y esto a largo plazo puede hacer que nuestro archivo requirements.txt se llene de basura o de dependencias no deseadas
Beneficios
Poetry al final del dia internamente usa virtualenv y pip, lo importante aquí es la capa de abstracción que crea incluyendo su CLI que pone a nuestra disposición para mejorar la productividad y evitar problemas a futuro sobre todo en producción, a continuación mencionaré los principales beneficios de poetry
- Dependencias de desarrollo utilizando solamente pip para lograr tener dependencias de desarrollo y de producción toca dar un montón de vueltas y se debe gestionar todo de manera manual, con poetry utilizamos solamente el siguiente comando
poetry add pdbpp -D
Nuestro archivo de configuración de poetry se veria asi
[tool.poetry]
name = "src"
version = "0.1.0"
description = ""
authors = ["jairo <me@jairoandres.com>"]
[tool.poetry.dependencies]
python = "^3.7"
[tool.poetry.dev-dependencies]
pytest = "^5.2"
pdbpp = "^0.10.2"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
observamos que las dependencias se agregan a [tool.poetry.dev-dependencies] ahora cuando el proyecto se mueve de maquina que es uno de los mayores sustos estas dependencias se pueden ignorar sencillamente con el comando
poetry install --no-dev
este comando solo instalará dependencias de producción
- Gestión de los entornos virtuales a veces trabajar con los virtualenvs puede ser un poco tedioso y más si tenemos diferentes entornos con diferentes versiones llenamos carpetas con entornos o incluso se ensucia el proyecto con carpetas de entornos, con poetry se puede gestionar varios entornos utilizando el comando
poetry env list
Este comando retorna los entornos que se han generado utilizando poetry
src-RXqvWCCk-py3.7
src-RXqvWCCk-py3.8
src-RXqvWCCk-py3.9 (Activated)
En mi caso tengo tres entornos utilizando diferentes versiones generados (ejemplo poetry env use python3.8) se puede cambiar de manera sencilla, gestionar y agregar uno nuevo en la carpeta predefinida por poetry
- Remover paquetes y sus dependencias anteriormente mencione que este es uno de los inconvenientes que sucede constantemente y que son difíciles de gestionar por lo tanto requieren más trabajo del que debería dedicarse, en poetry por ejemplo se tiene el archivo de configuración
[tool.poetry]
name = "src"
version = "0.1.0"
description = ""
authors = ["jairoufps <jairoandrescp@ufps.edu.co>"]
[tool.poetry.dependencies]
python = "^3.7"
Flask = "^1.1.2"
[tool.poetry.dev-dependencies]
pytest = "^5.2"
pdbpp = "^0.10.2"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
En este caso agregue flask y se puede apreciar que aquí no se tienen agregadas las dependencias de la librería, estas se agregan al archivo poetry.lock pero es transparente para el desarrollador, por lo tanto al remover un paquete como flask se remueven sus dependencias de manera automática como se ve en la Figura 5 genial!
poetry remove flask
- Empaquetamiento de código realizar el empaquetamiento de código solamente con pip como una librería requiere de varios pasos, en poetry solamente se debe agregar el folder en el cual se va instalar como librería, agregando la siguiente línea a nuestro archivo de configuración
packages = [{include="src"}]
agregue el folder src por que ahi es donde se encuentra el código que deseo instalar, luego de ello ejecuto el siguiente comando para instalarla como librería del sistema
poetry install
ahora en este caso ya se puede llamar al código como una librería cualquiera instalada como en el siguiente ejemplo
from src.myproject import Myproject
project_one = Myproject()
Estos beneficios descritos presentan a poetry como una herramienta totalmente alineada con la cultura pythonica, enfocar al desarrollador en lo realmente importante permitiéndole llegar a producción con la menor cantidad de problemas posibles relacionado con las dependencias
Conclusión
Al final del día como desarrolladores es conveniente tener aplicaciones que nos faciliten los ciclos y las entregas, es casi común encontrarnos el en mi maquina funciona o que raro? por este motivo herramientas como poetry nos ayudan a que las dependencias se gestionen de la mejor manera (tanto en entornos dev como prod) , darle una oportunidad en un nuevo proyecto es una gran idea para explotar los beneficios que ofrece poetry