Índice:
- Sección A. Estructurar un proyecto: apartado I, apartado II, apartado III, apartado IV, apartado V, apartado VI, apartado VII, apartado VIII, apartado IX, apartado X.
En este artículo daremos un breve paseo a las particularidades de los archivos involucrados en la generación de la aplicación .exe
.
Archivos involucrados
Como hemos visto en el artículo anterior (apartado VIII), hemos creado una batería de archivos para conseguir generar el .exe
:
-
.gitlab-ci.yml
, tarealaunch-build-exe
: lanzador en el pipeline de Gitlab de la Action de GitHub -
ci/github-build.yml
: Action de GitHub. -
app/main.spec
: especificaciones para la generación del.exe
. -
extra-hooks/hook-pydantic.py
: módulos y submódulos de pydantic.
Lanzamiento de la Action de GitHub
Empezamos por el principio: lo primero que ocurrirá es que el pipeline de Gitlab provocará el lanzamiento de la Action de GitHub:
En la tarea launch-build-exe
realizamos lo siguiente:
- En before_script añadimos los paquetes necesarios y copiamos los archivos
.env
. - Comprimimos el repositorio (excepto los archivos innecesarios).
- Configuramos git.
- Hacemos un clonado del repositorio de GitHub y borramos su contenido (con el fin posterior de actualizar su contenido).
- Descomprimimos el 'zip' en la carpeta del proyecto clonado.
- Añadimos dinámicamente el workflow para GitHub y limpiamos la carpeta origen (
ci
) - El último paso es hacer un commit y un push para actualizar el repo de GitHub y desencadenar la construcción.
Como última nota a este punto cabe destacar que solo se disparará la acción si se cumplen las condiciones establecidas.
Ejecución de la Action en GitHub
En el instante en que se actualiza el repositorio en GitHub se desencadena la Action que se encuentra .github/workflows
. En el 'github-build' podemos ver los siguientes pasos:
- Realizamos un
checkout
del repositorio. - Confirmamos que tenemos el archivo
.env.production
de producción. Si no existiera se daría por finalizado la Action. - Preparamos el entorno Python: instalación de Python, creación del entorno virtual
venv
, actualización depip
, instalar dependencias manualmente (por si alguna biblioteca no se instala automáticamente), instalar dependencias derequirements
, instalarpyinstaller
y las bibliotecas para los hook - Verificamos que los paquetes necesarios se han instalado.
- Instalamos WebView2 runtime (para pywebview) descargándolo de la URL de Microsoft.
- Compilamos la aplicación con PyInstaller, copiamos las DLL's necesarias y plugins de Qt6 a la carpeta
dist
. - Y, como punto final, publicamos el artefacto y generamos un tag.
Generación del .exe
con PyInstaller
En el archivo main.spec
tenemos las especificaciones detalladas de cómo se va a compilar la aplicación.
Sin embargo, necesitamos que los módulos de nuestra aplicación estén disponibles, por lo que utilizamos un hook personalizado (archivo hook-pydantic.py
) que se encargará de incluir explícitamente todos los submódulos de pydantic y pydantic_settings en la lista de importaciones ocultas. De esta forma evitamos que la compilación falle por falta de librerías.
Veamos las fases según nuestro main.spec
.
Recolección y preparación de archivos
Recogemos los datas necesarios. Para ello tenemos la función collect_all_data
con la que recorremos recursivamente la carpeta app
y añadimos todos los archivos necesarios a la colección de datas.
Añadimos las dependencias de sistema para incluirlas en el .exe
, buscamos y añadimos las DLL's de: site_packages
, qt6_base
, qt_bin
y qt_plugins
.
Añadimos los recursos de NiceGUI: archivos static
y las templates
.
Añadimos nuestro archivo de configuración .env.production
.
Añadimos un icono si existe (app/assets/icon.ico
).
Y añadimos las importaciones ocultas con hiddenimports
recolectadas por el hook.
Análisis y empaquetado
Ahora que tenemos todos los archivos, vamos a construir el paquete siguiendo los siguientes pasos:
- Análisis: analizamos
app/main.py
, los datas, las importaciones ocultas, y generamos los metadatos. Puedes ver que incluimos los PyQt6 manualmente. - Empaquetado: comprimimos el código fuente de Python y los módulos en un archivo
.pyz
. - Crear el ejecutable: creamos el ejecutable, que incluye el archivo
.pyz
del empaquetado, los bootloaders de PyInstaller, las propiedades (nombre, icono, compresión UPX, habilitado de la consola) - Ensamblaje final: se prepara la carpeta
dist
y se incluyen el.exe
, empaquetados del source code así como todo lo que fuera necesario.
La parte que suele dar más quebraderos de cabeza suele ser la de los hiddenimports.
Apuntes
Hay que tener en cuenta que este empaquetado es muy básico y solo incluye las necesidades mínimas. Tal como vaya creciendo la aplicación habrá que ir actualizando el guión de preparación del ejecutable.
Enlaces
Repositorio del proyecto:
Enlaces de interés:
- Uso de PyInstaller: https://pyinstaller.org/en/stable/usage.html#options-group-what-to-bundle-where-to-search
- Utilización de archivos
.spec
: https://pyinstaller.org/en/stable/spec-files.html - Sobre los hook: https://pyinstaller.org/en/stable/hooks.html
- Empaquetado de NiceGUI: https://nicegui.io/documentation/section_configuration_deployment#package_for_installation
Siguiente artículo:
- Sección A. Estructurar un proyecto: apartado X: Revisión de código, trabajo en equipo.
Top comments (0)