EJECUTABLES O DISTRIBUIBLES DE MÓDULOS PYTHON

AMANECE SOBRE LA BARANDA DEL SAUZAL, CON EL TEIDE AL FONDO Y EN PRIMER PLANO EL ACANTILADO DE ACENTEJO SOBRE UNA MAR EN CALMA, NORTE DE TENERIFE.

      Cuando hablamos de distribuir (distributable, en inglés) nuestros propios códigos (programas, scripts, etc.) convenientemente empaquetados (packaged), nos estamos refiriendo a la capacidad de poder enviarlos FUERA del directorio raíz donde se ubican a otras partes de nuestro propio equipo (carpetas, discos duros, memorias extraíbles, etc.) e, incluso, y esto es de lo más interesante, fuera del mismo (vía email, plataformas on line de distribución, etc.) y ser reutilizados y ejecutados desde sus NUEVAS ubicaciones.
El objetivo final de todo el proceso de CREAR CÓDIGO EMPAQUETARLO (packaged) DISTRIBUIRLO (distributable) REUTILIZARLO, consiste en implementarlo dentro de la raíz principal de la carpeta de Python, directamente vinculado a nuestro sistema operativo (linux, mac os, windows, etc.), de modo que sea LEGIBLE y ACCESIBLE desde el propio sistema operativo, dado que en última instancia, como "cerebro" de la máquina que es, será el encargado de llevar a buen puerto la distribución.

SETUP.PY


      Para conseguirlo primero tenemos que crear un archivo Python (nombre que le damos a nuestro archivo + .py) que llevará un nombre ESPECÍFICO, por ejemplo el que encabeza el capítulo, que es el más usado, aunque podemos escoger otro si queremos: setup.py,  que responde a una sintaxis particular y a una  modelización predeterminadas. Este archivo setup.py deberá vincularse al directorio raíz de Python, en nuestro sistema operativo.
¿Y qué puede contener este archivo setup.py? Básicamente información estructurada (no se trata de un script operativo en sentido estricto, ya que no contiene algoritmos ni bifurcaciones en su código: casi podría decirse de él que se trata de un archivo de sólo lectura, como un documento *.txt de andar por escritorio). ¿Sobre qué? Pues sobre las CARACTERÍSTICAS del paquete (recordamos que todo código que queramos distribuir debemos empaquetarlo antes, como ya hemos dicho) que queremos distribuir; su VERSIÓN (normalmente, si es la primera vez que distribuimos el paquete sería una numeración mínima y sencillita, como 0.0.1, 1.0, 1.0.0, o así. Para "redistribuciones" posteriores, con código aumentado, optimizado, actualizado, etc., podríamos ir añadiendo numeración creciente, por ejemplo, 1.0.1, 1.1, 0.0.2, ...; una DESCRIPCIÓN somera sobre el contenido del paquete; y, a partir de estos datos básicos, puede añadirse más información complementaria, como un copyright, un listado de contactos del autor (email, redes sociales, directorios profesionales), la versión de Python en la que se ha desarrollado el código, posibles urls de referencia, blogs participativos. etc.
Finalmente introducimos una variable, usualmente con el nombre packages, que contendrá una lista cuyos elementos, en orden de lo más genérico a lo más particular, irá dando cuenta de la ruta que va desde el directorio raíz hasta el directorio o carpeta donde se aloja el archivo *.py que queremos distribuir apoyándonos en la sintaxis del punto.




En este ejemplo tenemos la carpeta raíz (root folder) o directorio raíz de Python donde insertamos el archivo setup.py. Dentro del directorio raíz de Python guardamos tres subdirectorios o subcarpetas (subfolders) que deben contener necesariamente el archivo __init__.py, tal y como ya estudiamos en https://conocepython.blogspot.com/2017/01/t1-paquetes-packages-de-python.html
El primero de todos estos subdirectorios es __PYCACHE__, que es un directorio que crea Python solito ex profeso cada vez que construimos un paquete (package). A continuación tenemos dos subcarpetas más, geometría_plana con ficheros (módulos) relacionados con la geometría euclidiana y otro, áreas, que almacena cuatro ficheros (módulos) con fórmulas de áreas: areacuadrado.py, areatrapecio.pyareatriangulo.py y arearombo.py, respectivamente.

PINZÓN AZUL, PÁJARO EMBLEMÁTICO DE LA FAUNA DE TENERIFE.

Vayamos ahora con un ejemplo práctico donde localizamos un archivo (módulo .py) que queramos empaquetar y distribuir.
Primero, creamos un módulo __init__.py, vacío de contenido. Este fichero es como una señal, un cartel, una baliza, que le dice a Python que la carpeta donde se encuentra es un paquete y que tiene que considerarlo como tal.



Desde nuestro amado IDLE, por ejemplo, y desde el menú de herramientas, accedemos con file > open al directorio raíz de nuestra versión de Python.



En la carpeta SCRIPTS_PROPIOS guardamos nuestro módulo __init__.py, con lo que dicha carpeta pasa a convertirse por arte de magia pythoniana en un paquete de Python (package) con todas las de la ley.


El módulo en cuestión es areatriangulo.py:


Como podemos ver, una simple función definida por el usuario, con dos argumentos obligatorios: base y altura, y la cláusula return para que devuelva un resultado.
Para proseguir vamos a apoyarnos en un LIBRERÍA DE TERCEROS. La librería estándar de Python proporciona un módulo específico para tal fin, el módulo setuptools, pero nos parece que la opción de terceros con la librería cx_Freeze es mucho más directa y, por experiencia, menos "traumática" entre compatibilidades del SO de nuestro computador y los directorios de Python. Veamos cómo tenemos que proceder.
Antes de todo, al entrar en  python.org, seleccionar la versión estable de Python más adecuada para nuestro sistema operativo y comenzar con la descarga, el ejecutable nos mostrará la opción Add Python (versión) to PATH en la parte inferior, con una casilla de verificación a la derecha. Es una opción que debemos ACEPTAR para poder descargarnos librerías de terceros con el comando pip install. Vemos la secuencia para saber cómo hacerlo.




Y continuamos con la descarga sin mayores contratiempos. Con lo que acabamos de hacer nos aseguramos el poder instalar en nuestro directorio raíz de Python las librerías de terceros que nos puedan a ayudar a codificar mejor y con muchísimas más opciones nuestros proyectos.
Hecho esto, pasamos a descargarnos la librería cx_Freeze que citábamos antes. Vemos cómo.
Lo primero es escribir en el buscador de nuestro navegador preferido el nombre de la librería:





Hacemos clic en la dirección que rodeamos con un recuadro. Esto nos lleva a la siguiente página:


Ahora abrimos nuestra consola de comandos (también nos vale POWERSHELL si lo escribimos en el buscador de INICIO en windows 7, o su equivalente en otras versiones de windows). Si no encontramos la consola de comandos (también llamada Símbolo de sistema), podemos igualmente escribir cmd en el buscador.


Hacemos clic sobre la consola de comandos y la abrimos. Copiamos el texto de la propia página de cx_Freeze:
Y lo copiamos tal cual en la consola de comandos:


A continuación, ya sólo nos queda pulsar ENTER, y la descarga de la librería se llevará a cabo de manera automática, sin despeinarnos un sólo pelo.

      EN LA CAPTURA DE PANTALLA OBSERVAMOS QUE JUSTO DEBAJO DE COPIAR LA LÍNEA, SE MUESTRA EL SIGUIENTE TEXTO: already up-to-date: cx_Freeze in c:... ESTO SUCEDE PORQUE QUIEN ESCRIBE YA TIENE INSTALADA LA LIBRERÍA EN SU DIRECTORIO RAÍZ DE PYTHON. A QUIENES SE LA DESCARGUEN POR PRIMERA VEZ SE LES MOSTRARÁ UN MENSAJE DISTINTO. SOBRE LAS VIRTUDES Y CUALIDADES DE pip install HABLAREMOS MÁS ADELANTE EN UN NUEVO CAPÍTULO DEL MANUAL.

Pues bien ahora que ya tenemos instalada la librería cx_Freeze el siguiente paso es  construir  nuestro módulo setup.py que necesitamos para empaquetar y distribuir nuestro archivo areatriangulo.py. Veamos cómo hacerlo:


Tras la importación que necesitamos (from cx_Freeze import setup, Executable), llamamos a la función setup() y le proporcionamos los argumentos que mostramos en el ejemplo cuyos valores deberán expresarse como cadenas: name, version, description, author, url y executables. Para éste último, utilizamos una lista que contiene el método Executable() cuyo argumento es la propia dirección donde se encuentra alojado el módulo Python que queremos convertir en ejecutable (areatriangulo.py).
ADVERTENCIA: Tanto el módulo que queremos convertir en ejecutable como el módulo setup.py que nos va a permitir hacerlo DEBEN ESTAR EN LA MISMA CARPETA, lo que significa que la ruta (path) para uno y otro es la misma, como podemos ver en la parte superior del ejemplo, sobre el menú de herramientas, donde podemos leer la ruta del archivo setup.py y la ruta del archivo que queremos convertir en ejecutable como argumento de Executable(). Lo confirmamos:


Con esto hecho, volvemos a abrir nuestra consola de comandos (o POWERSHELL) y escribimos lo siguiente, para nuestro ejemplo, en el prompt:
CD C:\Users\Jose\AppData\Local\Programs\Python\Python36\SCRIPTS_PROPIOS ¬ INTRO
* Este comando nos sitúa en la ruta (path) que nos interesa (podemos copiar la dirección directamente de la cabecera de la página y pegarla tal cual en la consola) y nos abre el directorio SCRIPTS_PROPIOS.
C:\Users\Jose\AppData\Local\Programs\Python\Python36\SCRIPTS_PROPIOS>python setup.py build ¬ INTRO
* Al cabo del prompt escribimos python, el nombre de nuestro ejecutable (setup.py), el comando build y pulsamos INTRO.



Al pulsar INTRO nos proporciona una cascada de información sobre todos los procesos internos que han acontecido hasta completar su ejecución: Algo como lo que sigue:



Una vez completada la ejecución, regresamos a nuestra carpeta SCRIPTS_PROPIOS donde teníamos almacenados los archivos areatriangulo.py y setup.py y comprobamos que nos aparece una carpeta nueva, build, que antes no teníamos:


Ahora abrimos la carpeta build y nos encontramos que se nos muestra una subcarpeta (para nuestro ejemplo): exe.win-amd64-3.6, donde se aloja, entre otras cosas, nuestro ejecutable. La abrimos y nos encontramos con una nueva subcarpeta: lib. Pero sin salirnos de aquí, en la parte inferior derecha, pulsamos sobre python files, que es la opción que Python nos muestra por defecto en todas las carpetas de su directorio raíz, y seleccionamos la opción All files para que se nos muestren todos los archivos almacenados en la carpeta fuera cual fuese su extensión:
ADVERTENCIA: Cada vez que creemos un nuevo ejecutable se sobreescribirá nuestra carpeta build, por lo que conviene renombrarla, a ser posible, con un nombre que haga referencia a lo que contiene, como por ejemplo, ejecutable_areatriangulo.





 Y el resultado sería el siguiente:


Para comprobarlo podemos hacer clic con el botón derecho del ratón para llamar al menú contextual del sistema operativo y seleccionar la opción propiedades, normalmente, al final del listado.


Y desde aquí comprobar que, efectivamente, se trata de un archivo con extensión *.exe, exclusiva de las aplicaciones (ejecutables):


ATARDECER SOBRE EL SOMBRERO DE CHASNA, EN LOS ALTOS DE VILAFLOR, DENTRO DEL PERÍMETRO DEL PARQUE NACIONAL DE LAS CAÑADAS DEL TEIDE, SUR DE TENERIFE.

Pyinstaller

      
      Traemos una manera alternativa, muy sencilla pero eficaz (nuestra preferida, sin más) para obtener un ejecutable a partir de un módulo Python.
En este caso nos debemos descargar una nueva librería de terceros, Pyinstaller, por el procedimiento que ya hemos explicado más arriba mediante pip install:


A continuación presionamos INTRO y se nos descargará todas las dependencias necesarias (no son muchas, la verdad) que permitirán funcionar la librería:


ADVERTENCIA: En la captura superior se muestra una secuencia de líneas que comienzan con Requirement already satisfied. Esto se debe a que ya tengo instalada la librería: en vuestro caso, la información de la descarga será distinta.
Vamos a proceder a convertir en ejecutable un nuevo módulo de Python: C2.pyw (la extensión *.pyw es una extensión más entre otras asumida y asimilable al sistema de ficheros de Python, como nuestra *.py de toda la vida, *.pyc, *.pym, etc. En este caso, hablamos de un archivo de desarrollo cuyo nombre real es Python GUI Source File y que se utiliza para señalar archivos gráficos de Python).
Así pues, lo primero de todo es localizar en qué parte del directorio raíz de Python tenemos dormitando feliz el fichero (módulo) de nuestra elección. En nuestro caso, y de manera análoga al ejemplo anterior, tenemos nuestro archivo C2.pyw en la siguiente dirección:


Conociendo la ruta, en nuestra consola de comandos, tecleamos 1., que nos sitúa en el directorio de nuestro interés, y a continuación, en 2., tecleamos los sencillos comandos que necesitamos, con el nombre de nuestro archivo de nuestra elección:

pyinstaller --onefile C2.pyw

El modificador --onefile que situamos a continuación de pyinstaller nos permitirá compilar todos los archivos que se generan por defecto cuando pyinstaller construye un ejecutable. Esto nos permitirá externalizar  nuestro archivo ejecutable (C2.exe) y, no sólo ejecutarlo fuera del directorio raíz de python sino que, además, mucho más importante, ejecutarlo en cualquier equipo aún no teniendo instalado Python, vamos, el sueño dorado de cualquier programador.
Lo vemos a continuación:


Pulsamos INTRO y se producirá una cascada de dependencias y archivos autocreados que, si todo va bien, acabará generando nuestro ejecutable. Regresamos al directorio raíz de Python y nos situamos en el directorio SCRIPTS_PROPIOS. Observamos que aquí nos aparecen dos nuevas subcarpetas que antes no teníamos: build y dist.



ADVERTENCIA: Igual que sucedía con cx_Freeze, debemos renombrar las carpetas build y dist para que no se sobrescriban cuando queramos convertir a ejecutable un nuevo módulo de nuestro directorio.
Debemos poner nuestra atención en la carpeta dist, de distributable. La abrimos y en la parte inferior derecha, seleccionamos la opción All files, para que se nos muestre todos los ficheros almacenados en ella, a parte de los módulos específicos de Python. Entonces... ¡Oh sorpresa! He aquí nuestro archivo ejecutable C2.exe. Veámoslo:



Podemos, por ejemplo, sacarlo a nuestro escritorio y ejecutarlo aquí, fuera del directorio raíz de Python y comprobar si funciona:



Primero, haciendo clic con el botón derecho del ratón sobre el icono del 'presunto' ejecutable para que se nos abra el menú contextual certificamos que sí, que sí, que es un ejecutable como un castillo eligiendo la opción 'propiedades' (normalmente, la última opción del listado):



Pues bien, hacemos clic con el botón izquierdo sobre el icono del ejecutable y... ¡voilà!



Aquí tenemos abierta y perfectamente operativa nuestro ejecutable C2.exe fruto de la conversión como tal del módulo C2.pyw de Python.
Sin embargo, ¡qué mal se ve la consola de Python asomando por detrás, ¿verdad?! Bueno, pues para solucionar este problema podemos añadir un modificador propio de pyinstaller: --windowed, que nos ayudará a solventar esta situación. La sintaxis de comando sería entonces la siguiente:

pyinstaller --windowed --onefile C2.pyw

Pero aún podemos hacer más y rizar el rizo: podemos añadir nuestro propio icono (archivo *.ico) a nuestro ejecutable y proporcionarle una presentación más significativa y asociable a su funcionalidad. ¿Cómo podemos hacer esto? Bien. Vayamos por partes.
Lo primero de todo es, obviamente, construir nuestro icono. Para hacer esto podemos recurrir a sitios online que hagan el trabajo por nosotros: https://imagen.online-convert.com/es/convertir-a-ico, resulta una buena opción.
Vamos a la página en cuestión y en el cuadro inferior con  fondo verde, hacemos clic sobre la opción🔍Seleccionar archivos y subimos cualquier imagen que tengamos almacenada en nuestro disco duro.


Una vez hayamos elegido nuestro archivo gráfico (en nuestro caso hemos elegido un archivo gráfico con extensión *.jpg) como el que muestra la imagen:

md.jpg

... podemos, antes de convertirla a un archivo *.ico, configurar sus dimensiones (recomendamos 200x200 píxeles. Y si podemos recortarla antes con algún otro programa que ya tengamos instalado en nuestro equipo, mejor). Lo vemos en la captura inferior:



Una vez satisfechos con nuestra imagen, pulsamos sobre la opción Iniciar conversión y, de manera automática, se nos descargará en nuestro equipo, normalmente, en Windows, en la carpeta de Descargas.
Ya tenemos nuestro archivo md.ico. Ahora debemos colocarlo en la misma carpeta donde tenemos el archivo Python (C2.pyw) que queremos convertir, en nuestro ejemplo, SCRIPTS_PROPIOS.



Para acabar, ya sólo nos falta añadir un último modificador, también propio de pyinstaller, que nos permitirá enmascarar nuestro ejecutable con el icono que hemos escogido. Lo hacemos con el comando --icon=md.ico, con lo que el comando completo final quedará como:


pyinstaller --windowed --onefile --icon=md.ico C2.pyw

Por cierto, el orden en que escribamos los modificadores no es relevante, aunque es preferible que el modificador de icono, --icon=md.ico, se coloque justo antes del nombre del archivo que vamos a convertir en ejecutable.
Veámoslo en la consola:



Pulsamos INTRO para que corra la consola, se cargarán los ficheros que necesita pyinstaller para crear nuestro ejecutable, y en nuestra carpeta SCRIPTS_PROPIOS deberán aparecer las carpetas dist, que es donde se guarda nuestro flamante archivo C2.exe, y build. Recordar una vez más que debemos renombrarlas para que no se sobrescriban cada vez que construyamos un nuevo ejecutable.
Procedemos a abrir nuestra carpeta dist y seleccionar en el cuadro de texto en la esquina inferior derecha la opción All files, para que se nos muestren todos los ficheros que contiene y no sólo los de Python. Observaremos con sorpresa y temblor de manos que sólo hay uno (normalmente): justo el que esperábamos encontrar: C2.exe.



Lo externalizamos, por ejemplo, al escritorio, fuera de las garras del directorio raíz de Python:




Y, finalmente, presas de un ataque de nervios, abochornados por la incertidumbre, al borde del pánico más paralizante, hacemos doble clic izquierdo sobre el icono...




¡FUNCIONA!😂😂😂


RETAMAS EN FLOR CUANDO LA PRIMAVERA LLEGA A LAS ALTURAS DEL PARQUE NACIONAL DE LAS CAÑADAS DEL TEIDE, CON EL VOLCÁN TEIDE AL FONDO. CENTRO DE TENERIFE.




No hay comentarios:

Publicar un comentario