Ya 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 todo.

Agregar assets a PyInstaller, resolver rutas y empaquetar

Agregar assets a PyInstaller, resolver rutas y empaquetar

En fin, ahora aquí está la parte 2 en donde muestro cómo agregar assets a nuestro paquete. Por ejemplo, a veces es necesario agregar imágenes, canciones o cualquier archivo extra al empaquetar con pyinstaller.

Cabe mencionar que no fue nada fácil, ya que casi no encontré documentación sobre eso excepto en el sitio oficial.

Lo que vamos a hacer

Será simple. Aprovechando que acabamos de ver cómo leer un archivo de texto, haremos que ese archivo de texto sea empaquetado junto con el ejecutable. Que sea simple no significa que funcione, ya que con el ejemplo que pondré se verá cómo agregar más assets de todo tipo.

Requisitos y recomendaciones

Recuerda mirar el tutorial anterior, estás forzado a ello. Aparte de eso, aquí puedes ver más tutoriales de Python.

Paso 1: crear y modificar el archivo spec

Cuando ya tengas listo tu código, empaquétalo normalmente como quieras. En mi caso tengo el archivo main.py con el siguiente código:

Así que para empaquetarlo en un .exe ejecuto lo siguiente:

pyinstaller --onefile main.py

Luego de esperar un momento, se creará lo necesario. Voy a omitir las cosas básicas porque ya las puse en el tutorial anterior. Ahora, lo importante es un archivo con extensión .spec que se ha creado. Su nombre debe ser el mismo que nuestro script principal, así que en mi caso se llama main.spec.

Archivo spec creado por pyinstaller

Archivo spec creado por pyinstaller

Ahora vamos a agregar código (porque es código de Python) de manera que se añadan datos al valor datas de a. Así:

a.datas += [("ruta_absoluta_al_archivo", "ruta_al_archivo_que_usamos_en_el_código", "DATA")]

Dentro del arreglo [] podemos agregar las tuplas necesarias, con 3 elementos en cada una de ellas… una tupla por cada archivo.

De manera que solamente cambian las dos primeras cosas, ya que DATA se queda intacto. En mi caso agregaré el archivo archivo.txt así que mi spec queda así:

a.datas += [("./archivo.txt", "archivo.txt", "DATA")]

Si fuera necesario, agregaría más tuplas separadas por coma; siempre dentro del arreglo. Para que quede más claro, ahora mi archivo spec se ve así:

Modificar datas en PyInstaller para agregar assets

Modificar datas en PyInstaller para agregar assets

Ahora sí ya estamos listos. Por cierto, ya no ejecutes pyinstaller con el script, porque va a sobrescribir el archivo spec. Déjalo intacto, sólo si haces cambios entonces genera de nuevo y modifica.

Paso 2: crear función que resuelve rutas

Lo que sigue es crear una función que resuelva las rutas dependiendo del entorno. Si estamos en desarrollo normalmente, resolverá la ruta normal. Pero si ya está empaquetado, resolverá la ruta en donde se desempaquetan los assets.

Gracias a _MEIPASS sabremos si ya estamos “empaquetados” o todavía no. Esta ruta de _MEIPASS es en donde PyInstaller coloca los assets que le indicamos.

En caso de que no estén empaquetados, la ruta se resuelve normalmente. Por cierto, la función necesita que exista os y sys, por eso es que se importan al inicio.

Paso 3: cambiar rutas

En cada lugar en donde se invoque a un archivo, vamos a cambiarlo para que ahora su ruta sea lo que devuelve resolver_ruta. Por ejemplo, el código para leer el archivo indica así la ruta:

nombre_archivo = "archivo.txt"

Pero ahora lo cambiaré para que sea lo siguiente:

nombre_archivo = resolver_ruta("archivo.txt")

En tu caso cámbialo por cada imagen, canción o lo que sea. Antes de empaquetar todo, prueba tu código normalmente para ver si realmente se resuelven las rutas.

Paso 4: poniendo todo junto

Como mi script es sencillo, puse la función que resuelve rutas dentro del mismo. Por cierto, agregué un mensaje de “presiona Enter para salir” (usando input) al final para que al ejecutarlo no se cierre inmediatamente. Todo el código queda así:

También agregué mi main.spec para que quede de referencia.

Paso 5: hora de empaquetar

Este paso es el más importante. Ahora no haremos esto:

pyinstaller --onefile main.py

Sino que vamos a pasar el nombre del spec, así:

pyinstaller --onefile main.spec

Si no lo haces así, se va a sobescribir el main.spec.

Después de eso podemos ir a la carpeta dist en donde ejecutamos el comando, y estará un ejecutable con el nombre de nuestro script, en mi caso main.exe.

¿No crees que funcione? te invito a descargar el ejecutable. Si se lee el archivo, significa que sí pude empaquetar el asset.

Vídeo

Aquí hay un vídeo con todos los pasos que se explican en el post:

Conclusiones

PyInstaller y el archivo spec permiten hacer más cosas. En este caso vimos cómo agregar archivos al ejecutable, pero se pueden hacer más cosas.

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

1 Comment

Empaquetando scripts de Python en un .exe o ejecutable utilizando PyInstaller - Parzibyte's blog · diciembre 27, 2018 a las 7:00 pm

[…] 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 […]

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: