Empaquetando scripts de Python en un .exe o ejecutable utilizando PyInstaller

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:

pip install pyinstaller

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:

pyinstaller foto_camara_nombres.py

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í:

pyinstaller --onefile foto_camara_nombres.py

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.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

15 comentarios en “Empaquetando scripts de Python en un .exe o ejecutable utilizando PyInstaller”

  1. Hola, estoy haciendo código basado en las librerías PDF2IMAGE y PYTESSERACT para leer desde remitos escaneados en PDF el N° de ese remito y renombrar cada archivo con ese N° para identificarlos y almacenarlos en un servidor. Lo hice funcionar en mi PC donde instale dichas librerías pero al convertirlo en .EXE (en carpeta o en un solo archivo) con PYINSTALLER y tratar de ejecutarlo en la PC de mi trabajo (sin permisos para instalar las librerías) no funciona. ¿No se supone que al crearse el .EXE se incluyen todos los archivos para ejecutarlo en cualquier PC? Desde ya muchas gracias!

  2. Hola gracias por tu explicación…en mi caso quiero hacer ejecutable mi codigo, es un buscador en tkinter que se conecta a un txt(todo dentro de la misma carpeta), hice todos los pasos pero cuando abro el .exe me sale el siguiente nameError: name is ‘true is not defined’ podrias ayudarme?

    1. Hola. No conozco ningún software para agregar una licencia; la lógica debería ser implementada en Python o algo así, usando sus propios métodos. Por otro lado, recuerde que el código puede ser decompilado así que no tendría mucho sentido poner licencia si el usuario final podrá modificar el código.

  3. 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

    1. 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

  4. Pingback: Pyinstaller parte 2: agregar assets, imágenes y archivos a ejecutable de Python - Parzibyte's blog

Dejar un comentario

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