summaryrefslogtreecommitdiff
path: root/es/07_install.md
blob: af18b1c696329387ae45a1a3229b4f34a02ed80d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# 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 nos aseguramos de instalar con python la herramienta `pip`.
Que sirve para instalar paquetes nuevos en el sistema de forma sencilla.

## Sobre 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 usar 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

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

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 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
```

>  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:  
<https://packaging.python.org/guides/tool-recommendations/>


## 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 perder 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.