Python con poesía parte 1

8 min(s) Fecha: 2022-02-11

Una forma sencilla de gestionar las dependencias en tu proyecto.

Desarrollar una aplicación en Python actualmente, requiere un control exhaustivo de las dependencias que en muchos casos, las soluciones actuales, no proveen ó en el peor de los casos... Que tú mismo lo resuelvas como puedas...

Poetry es una herramienta para la gestión de dependencias y empaquetado en Python. Te permite declarar las bibliotecas de las que depende tu proyecto y las gestionará por ti.

Hasta aquí, nada nuevo bajo el sol, de momento...
-- un visitante del blog

Correcto, Lo mágico de Poetry, es lo que ofrece y la forma como ofrece la gestión de las dependencias. 🎉


Instalación

Poetry requiere Python3.7 ó superior, para nuestro ejemplo, usaremos Python3.9

 curl -sSL https://install.python-poetry.org | python3.9 -

Al momento de escribir este post:

 poetry --version
Poetry version 1.1.12


Iniciando

De aquí en adelante no usaremos el tradicional archivo requirements.txt

Espera... qué?
-- un visitante del blog

En vez de eso, utilizaremos un archivo llamado pyproject.toml en el cual estará toda la información de la gestión de las dependencias y todo lo que comentamos anteriormente.

El archivo pyproject.toml utiliza la sintaxis toml y su configuración, para proyectos de Python, está detallada en el PEP 518.

Poetry permite definir secciones, para el nombre de nuestro proyecto, la versión, el autor ó los autores, la licencia etc....

Ejemplo:

[tool.poetry]
name = "my awesome project"
version = "1.0.0"
description = "awesome project with poetry"
authors = ["Jorge Brunal Pérez <diniremix@gmail.com>"]
license = "LGPL-2.1-only"
readme = "README.md"

ademas de:

Ejemplo:

[tool.poetry]
homepage = "https://awesome-site.org/projects/awesome-project"
repository = "https://gitlab.com/awesome-user/awesome-repo"
documentation = "https://awesome-site.org/docs/awesome-project"

keywords = ["awesome", "flask", "python"]

classifiers = [
    "Framework :: Flask",
    "License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)",
    "Operating System :: OS Independent",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3.9",
    "Development Status :: 5 - Production/Stable",
    "Topic :: Software Development :: Libraries :: Python Modules",
    "Topic :: Utilities",
]

[tool.poetry.urls]
"Bug Tracker" = "https://gitlab.com/awesome-user/awesome-repo/-/issues"

El PEP 517 introduce una forma estándar de definir sistemas de construcción alternativos para construir un proyecto Python. Poetry es compatible con PEP-517, proporcionando una biblioteca de núcleo ligero, por lo que debemos hacer referencia a él, agregando una sección llamada build-system en nuestro archivo pyproject.toml:

Ejemplo:

[build-system]
requires = ["poetry-core>=1.1.0"]
build-backend = "poetry.core.masonry.api"

Muy bonito y todo pero... y las depedencias...
-- un visitante del blog

Sigue leyendo 👇

Manejando las Dependencias 🚚

En tu archivo pyproject.toml define la lista de dependencias:

# lista de las dependencias básicas
[tool.poetry.dependencies]
# Tenga en cuenta que es obligatorio declarar la versión de python
# para la que su proyecto ó paquete es compatible
python = "~3.9"

Flask="2.0.1"
SQLAlchemy="1.4.25"
Flask-SQLAlchemy="2.5.1"
jsonschema="4.0.1"
loguru="0.5.3"

# se definen dependencias opcionales
# algunas de las cuales se incluyen mas abajo
# en la sección "extras"
PyMySQL = { version = "0.10.1", optional = true }
pandas = { version = "1.2.2", optional = true }

# lista de dependencias opcionales
[tool.poetry.extras]
mysql = ["PyMySQL"]
pandas = ["pandas"]

# dependecias de desarrollo
[tool.poetry.dev-dependencies]
black = "21.10b0"
pylint = "2.11.1"
isort = "^5.10.1"

Como habrás notado, las secciones permiten separar cada conjunto de dependencias 🎉 😏

En este punto, llevamos lo siguiente:



Creación del Entorno de trabajo

En otras ocasiones crearías un entorno virtual con virtualenv, pyenv, Pipenv etc... luego entrarías a ese entorno (activarlo) y se procedería a instalar las dependencias, usando pip ó pipenv.

Poetry se encarga de manera transparente de toda estas operaciones a través de su linea de comandos. 💻 🚀

Creamos la carpeta donde se instalarán las librerías y utilizamos la versión de Python que especificamos en el pyproject.toml.

 poetry env use python3.9

La salida será algo como:

Creating virtualenv my awesome project in /home/diniremix/awesome-project/.venv
Using virtualenv: /home/diniremix/awesome-project/.venv

Si revisamos la carpeta de trabajo...

 ls -la
total 16
drwxr-xr-x  3 diniremix diniremix 4096 feb 11 21:48 .
drwxr-xr-x 10 diniremix diniremix 4096 feb 11 21:46 ..
-rw-r--r--  1 diniremix diniremix 1636 feb 11 21:47 pyproject.toml
drwxr-xr-x  4 diniremix diniremix 4096 feb 11 21:48 .venv

El comando anterior ha creado la carpeta .venv donde se instalarán todas las dependencias, esto incluye las de desarollo, las opcionales, scripts etc...

En este momento, antes de instalar las dependencias, tu archivo pyproject.toml debe lucir como sigue:

[tool.poetry]
name = "my awesome project"
version = "1.0.0"
description = "awesome project with poetry"
authors = ["Jorge Brunal Pérez <diniremix@gmail.com>"]
license = "LGPL-2.1-only"
readme = "README.md"
homepage = "https://awesome-site.org/projects/awesome-project"
repository = "https://gitlab.com/awesome-user/awesome-repo"
documentation = "https://awesome-site.org/docs/awesome-project"
keywords = ["awesome", "flask", "python"]
classifiers = [
    "Framework :: Flask",
    "License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)",
    "Operating System :: OS Independent",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3.9",
    "Development Status :: 5 - Production/Stable",
    "Topic :: Software Development :: Libraries :: Python Modules",
    "Topic :: Utilities",
]

[tool.poetry.urls]
"Bug Tracker" = "https://gitlab.com/awesome-user/awesome-repo/-/issues"

[tool.poetry.dependencies]
python = "~3.9"
Flask="2.0.1"
SQLAlchemy="1.4.25"
Flask-SQLAlchemy="2.5.1"
jsonschema="4.0.1"
loguru="0.5.3"
PyMySQL = { version = "0.10.1", optional = true }
pandas = { version = "1.2.2", optional = true }

[tool.poetry.extras]
mysql = ["PyMySQL"]
pandas = ["pandas"]

[tool.poetry.dev-dependencies]
black = "21.10b0"
pylint = "2.11.1"
isort = "^5.10.1"

[build-system]
requires = ["poetry-core>=1.1.0"]
build-backend = "poetry.core.masonry.api"

Pregunta: ¿todos los campos y secciones comentadas arriba, son obligatorias?

-- un visitante del blog

Claro que no, sin embargo ten en cuenta que la información incluida en cada sección y llave del archivo pyproject.toml, permite especificar con claridad la finalidad del proyecto, donde esta ubicado, el creador, las herramientas que usa etc...

He aquí un ejemplo de las secciones y claves requeridas:

[tool.poetry]
name = "my awesome project"
version = "1.0.0"
description = "awesome project with poetry"
authors = ["Jorge Brunal Pérez <diniremix@gmail.com>"]

[tool.poetry.dependencies]
python = "~3.9"
# al menos una dependencia
# ejemplo:
Flask="2.0.1"

[build-system]
requires = ["poetry-core>=1.1.0"]
build-backend = "poetry.core.masonry.api"

Instalar las dependencias:

 poetry install

La salida será algo como:

Updating dependencies
Resolving dependencies... (16.0s)

Writing lock file

Package operations: 27 installs, 0 updates, 0 removals

   Installing markupsafe (2.1.1)
   Installing click (8.0.4)
   Installing greenlet (1.1.2)
   Installing itsdangerous (2.1.1)
   Installing jinja2 (3.0.3)
   Installing lazy-object-proxy (1.7.1)
   Installing typing-extensions (4.1.1)
   Installing werkzeug (2.0.3)
   Installing wrapt (1.13.3)
   Installing astroid (2.8.6)
   Installing attrs (21.4.0)
   Installing flask (2.0.1)
   Installing isort (5.10.1)
   Installing mccabe (0.6.1)
   Installing mypy-extensions (0.4.3)
   Installing pathspec (0.9.0)
   Installing platformdirs (2.5.1)
   Installing pyrsistent (0.18.1)
   Installing regex (2022.3.15)
   Installing sqlalchemy (1.4.25)
   Installing toml (0.10.2)
   Installing tomli (1.2.3)
   Installing black (21.10b0)
   Installing flask-sqlalchemy (2.5.1)
   Installing jsonschema (4.0.1)
   Installing loguru (0.5.3)
   Installing pylint (2.11.1)


Lista de comandos útiles

# Crear el entorno.
 poetry env use python3.9
# Instalar todas las dependencias (incluídas las de desarollo).
 poetry install
# Instalar sólo las librerías principales.
 poetry install --no-dev
# Instalar solo las dev-dependencies
 poetry install --no-root
# Instalar librerías sin agregarla directamente al pyproject.toml
 poetry add jsonschema
# Instalar una librería de desarrollo.
 poetry add -D flake8
# Instalar dependencias opcionales (extras).
 poetry install --extras "mysql"

# ó de la forma
 poetry install -E mysql

# Instalar varias dependencias opcionales al tiempo.
 poetry install --extras "mysql pandas"

# ó de la forma
 poetry install -E mysql -E pandas
# Listar todas las liberías instaladas.
 poetry show
# Buscar una librería (mestra la info del paquete y la versión)
 poetry search flask
# Desinstalar una libería.
 poetry remove jsonschema

En la próxima entrada, usando la configuración citada arriba, agregaremos la configuración para herramientas de terceros scripting y más!



Referencias