Introducción

Python es un lenguaje multiplataforma muy poderoso. Sirve para miles de cosas, pero hay algo que dificulta su “distribución” a los usuarios finales.

Es decir, no podemos mandarle un script con extensión .py a un cliente y decirle que instale Python, lo ponga en la variable PATH y lo ejecute desde la terminal.

Además… ¿qué pasa si nuestro script tiene dependencias? o si son muchos scripts, o cosas de esas.

Debido a esto, necesitamos algo así como un creador de ejecutables de Python. Una cosa que empaque todo en un archivo .exe (o al menos en un .zip) y que, sin necesidad de que en la máquina del usuario exista Python, se pueda ejecutar.

Justamente hoy venimos a hablar de eso: cómo crear un ejecutable de archivos de Python, utilizando PyInstaller.

Actualización

He creado la parte 2 de este tutorial en donde se ve cómo agregar assets al ejecutable. De esta manera puedes agregar imágenes, canciones o texto, cualquier archivo.

Requisitos para crear ejecutable de Python

Contar con Python (obviamente) y pip. Aquí un tutorial: instalar python.

Instalar PyInstaller

Si ya tenemos instalado pip, ejecutamos lo siguiente en nuestra consola:

Esperamos un rato a que se termine de instalar, y listo. Aquí dejo un enlace a la documentación oficial por si tienes problemas.

En mi caso, salió como se ve en la imagen. A todos nos saldrán diferentes cosas, tal vez; pero lo importante es que al final diga Successfully.

Instalar PyInstaller para empaquetar o generar archivos ejecutables en Python

Instalar PyInstaller para empaquetar o generar archivos ejecutables en Python

¡Listos para empaquetar!

¿Cómo funciona el empaquetamiento?

Yo tampoco lo sé, pero a grandes rasgos, pone el intérprete de Python y nuestros scripts en una carpeta (o archivo, como veremos más abajo) que puede ser distribuida a diferentes usuarios.

Explicaré dos opciones. Una para generar todo en una carpeta; y dentro de esa carpeta poner un .exe (que después podemos comprimir), y otra para (la que más me gusta) generar un archivo.exe independiente.

Nota: esto no protege nuestro código. Es decir, cualquiera podrá (no sé cómo, pero se puede) modificarlo.

Código de ejemplo

Vamos a utilizar el código en donde tomamos una foto de la webcam. Si no tienes webcam, o sólo quieres probar, haz un hola mundo y listo.

Generar una carpeta con ejecutable

Primero veremos cómo generar una carpeta que tendrá todo lo necesario para ejecutar nuestro código. Comencemos creando una carpeta nueva, en donde residirá nuestro código; esto lo hago más que nada para organizar las cosas, pero no es necesario crear nada.

En esa carpeta pondré el único script que se encarga del funcionamiento. Hasta el momento, se ve así:

Directorio en donde crearemos carpeta contenedora

Directorio en donde crearemos carpeta contenedora

Ahora navegaré hasta ahí desde la terminal, y escribiré lo siguiente:

Simplemente estoy llamando al ejecutable pyinstaller, y le paso como argumento el nombre de mi script.

Empaquetando script con PyInstaller

Empaquetando script con PyInstaller

Esto puede tardar un poco,  e incluso mostrar advertencias. Pero tranquilos, que las advertencias advertencias son. Mientras no genere un error, todo va bien. Me parece que el tiempo que tarda depende de las dependencias.

Proceso de empaquetado terminado

Proceso de empaquetado terminado

Como lo dije, tarda pero al final funciona. Miraré ahora la carpeta en donde ejecuté este comando… ahora tiene otros directorios, pero lo que nos importa es el que dice dist. Dentro de él, está todo lo que necesitamos para ejecutar nuestra app.

Directorio dist generado por PyInstaller

Directorio dist generado por PyInstaller

Ahora podemos comprimir toda esa carpeta, mandarla a nuestro cliente y decirle que ejecute el archivo .exe. O crear un instalador que copie todo eso y genere un acceso directo. Notar por favor que todos los demás archivos son necesarios, no sólo el .exe.

Si queremos todo en un archivo .exe, sigamos leyendo.

Generar un sólo archivo ejecutable

La mayoría queremos esto. Empaquetar todo lo necesario en un archivo ejecutable. Doble click y listo. Para ello, es casi como hace un momento, pero pasamos la opción –onefile. Así:

Con eso tenemos. Es un buen momento para mencionar que al abrir la aplicación, se tardará un poco más. Yo lo probé y no noté ninguna diferencia significante, pero sería de probar por nosotros mismos.

Archivo ejecutable (.exe) generado con éxito

Archivo ejecutable (.exe) generado con éxito

Ahora en dist sólo está el archivo binario. Y ese ya trae todo para ejecutar Python sin tenerlo instalado.

Directorio en donde se encuentra el archivo ejecutable

Directorio en donde se encuentra el archivo ejecutable

Probar ejecutable

Si tienes dudas, o si no crees que esto funcione, aquí dejo el ejecutable que yo mismo generé. Puedes confiar en él; lo que hace es tomar una foto de la webcam y guardarla en tu disco duro, sólo eso.

En fin, descárgalo bajo tu responsabilidad. Lo dejo alojado en Mega porque WordPress no me permite cargar archivos de ese tipo.

 

Conclusión

Esto nos brinda la posibilidad de generar ejecutables que podemos distribuir fácilmente por todo el mundo. Si lo combinamos con Cython, creo que ahora sí podremos proteger el código para que no sea modificado.

Este “generador” funciona en cualquier plataforma. Es decir, si queremos, también podemos portarlo para Linux o Mac; eso sí, necesitamos compilarlo en la misma plataforma que deseamos distribuirlo. En pocas palabras, si lo quieres en Linux, compila en Linux, si lo quieres para Mac, en Mac. Y si lo quieres en Windows, pues ya sabes, ¿no?

Dejo aquí la documentación oficial a PyInstaller. Eso es todo.

Estoy interesado en trabajar contigo de manera remota para llevar tu idea a la realidad, formar parte de tu equipo de desarrolladores, ayudarte con tu tarea, dar asesorías y todo lo relacionado con tecnología y programación. Contáctame para más información
No te vayas sin seguirme en Twitter, Facebook y GitHub
Si tienes dudas déjalas en un comentario, pero asegúrate de seguirme antes como agradecimiento (no te cuesta nada y me ayudas mucho)


parzibyte

He trabajado por más de 4 años en el desarrollo de software con experiencia en Java, PHP, JavaScript, HTML, Node.JS, Python, Android y Go. También he trabajado con bases de datos SQL como MySQL y SQLite, así como con bases de datos NoSQL usando MongoDB. Soy bueno utilizando algunos frameworks y herramientas como Firebase, jQuery, AngularJS, VueJS, CodeIgniter, Laravel, BulmaCSS, Bootstrap y Electron. Otros términos que conozco son: Arduino, GraphQL, API's, REST, AJAX, PouchDB, CouchDB, Experiencia de usuario, buenas prácticas de programación, Webpack, NPM, Administración de servidores y programación de scripts La plataforma en la que tengo más experiencia es la web, pero en mis ratos libres realizo unos pequeños ejercicios en C# y C. Estoy aquí para ayudarte a resolver tus problemas de programación y depuración :-)

5 Comments

Jaime · diciembre 27, 2018 a las 10:04 am

Me ha funcionado, pero necesito incluir imágenes y dependencias de python que utilizo en el script como “pyserial”, ¿Se podría conseguir?
Saludos.

Sebastian · enero 23, 2019 a las 8:35 am

Hola, buenas.
Muy bueno tu tutorial, con programas chicos me funciona bien pero tengo uno que usa pyqt5 para generar una interfaz con botones y esas cosas. El tema es que cuando ejecuto el comando que explicas acá genera bien el .exe pero al darle doble click no me carga nada y desconozco si faltará hacer otro paso.

Gracias

    parzibyte · enero 23, 2019 a las 8:43 am

    Me parece que específicamente para PyQt hay otro proceso que se indica en la página oficial, ya que pyinstaller no funciona con la librería. Espero tener tiempo de traer un tutorial sobre ello muy pronto

Pyinstaller parte 2: agregar assets, imágenes y archivos a ejecutable de Python - Parzibyte's blog · diciembre 27, 2018 a las 6:58 pm

[…] ha pasado algún tiempo desde que escribí cómo empaquetar un archivo de Python en un ejecutable. No pensé que tuviera el impacto que tuvo, pero me da gusto al final de […]

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

A %d blogueros les gusta esto: