None

Python: Exe erstellen mit PyApp

width="1024" height="576" sizes="auto, (max-width: 1024px) 100vw, 1024px">PyApp bringt Python-Programme (relativ) schnell und einfach in eine kompakte, ausführbare Form. Henner Damke | shutterstock.com



Jeder Entwickler weiß, dass es schwierig ist, ein Python-Programm als eigenständiges, ausführbares Paket zu redistribuieren. Zwar gibt es für diese Aufgabe Lösungen von Drittanbietern. Die bringen jedoch Nachteile mit sich:




PyInstaller ist das älteste und bekannteste Tool für diesen Task. Leider ist es auch umständlich zu handhaben und erfordert einige Experimentierphasen, bevor ein funktionierendes, verteilbares Paket dabei herauskommt.



Nuitka ist hingegen ein neueres Projekt, das Python-Programme zu weiterverteilbaren Binärdateien kompiliert. Die resultierenden Artefakte können allerdings sehr groß sein. Sie zu erstellen, dauert dann auch entsprechend lange.




Einen völlig anderen Ansatz verfolgt hingegen die Paketierungslösung PyApp. Die in Rust geschriebene Utility kompiliert aus dem Quellcode und bezieht dabei Informationen über das Python-Projekt mit ein. Das Resultat ist eine eigenständige Binärdatei, die Ihr Projekt mit einem Klick in ein Verzeichnis entpackt und dort ausführt.



PyApp einrichten



Im Gegensatz zu anderen Python-Distributionslösungen wie PyInstaller handelt es sich bei PyApp nicht um eine Python-Bibliothek – und auch nicht um ein Standalone-Programm. Vielmehr erstellen Sie für jedes Python-Programm, das Sie verteilen wollen, eine benutzerdefinierte Version von PyApp. Allerdings gilt es einige Voraussetzungen zu erfüllen, bevor Sie PyApp dazu verwenden können, Python-Programme bereitzustellen:




PyApp-Quellcode: Erstellen Sie einen Klon des Quellcodes und speichern Sie diesen in einem eigenen Verzeichnis, getrennt von anderen Projekten.



Rust-Compiler und Infrastruktur: Wenn Sie mit Rust oder den dazugehörigen Tools nicht vertraut sind, sollten Sie sich zumindest so viel Wissen aneignen, um ein Rust-Programm aus dem Quellcode kompilieren zu können. Dieses Rust-Grundlagentutorial ist zu diesem Zweck zu empfehlen.



Python-Programm im Binärformat: Das „Wheel” oder die .whl-Datei ist das Binary Format, das verwendet wird, um Python-Programme zusammen mit plattformspezifischen Komponenten (wie vorkompilierten Bibliotheken) zu verpacken. Wenn Sie noch kein Wheel für das Python-Programm haben, das Sie neu verpacken möchten, müssen Sie eines erstellen. Sie können auch Wheels verwenden, die auf PyPI gehostet werden.




Um herauszufinden, welches Python-Projekt Sie kompilieren möchten und wie es unterstützt werden soll, verwendet PyApp im Rahmen des Build-Prozesses Umgebungsvariablen. Die folgenden kommen dabei am häufigsten zum Einsatz:




PYAPP_PROJECT_NAME wird verwendet, um den Namen des Python-Projekts zu definieren, das Sie paketieren möchten. Wenn Sie pyproject.toml genutzt haben, um Ihr Projekt zu definieren, sollte es mit dem Attribut project.name übereinstimmen. Das kann auch der Name eines Projekts auf PyPI sein. Anderenfalls sollten Sie den Pfad zur entsprechenden .whl-Datei definieren.



PYAPP_PROJECT_VERSION kommt zum Einsatz, um bei Bedarf eine bestimmte Version des Projekts zu konfigurieren.



PYAPP_PROJECT_PATH ist der Pfad (relativ oder absolut) zur .whl-Datei, die Sie für Ihr Projekt verwenden. Wenn Sie nur eine .whl von PyPI installieren, können Sie das ignorieren.



PYAPP_EXEC_MODULE ermöglicht es, festzulegen, welches Modul verwendet werden soll, um Python Packages automatisch auszuführen. Nutzt Ihr Programm dafür thisprogram, würde daraus resultieren: python -m thisprogram.



PYAPP_EXEC_SPEC ist für Programme gedacht, die über ein Entry-Point Skript verfügen. Dabei deckt sich die Syntax mit dem Abschnitt project.scripts von pyproject.toml. So würde etwa pyprogram.cmd:main das Modul pyprogram.cmd aus den Modulen Ihres Python-Programms importieren und darüber die main()-Funktion ausführen.



PYAPP_EXEC_SCRIPT definiert den Pfad zu einem beliebigen Python-Skript, das in die Binärdatei eingebettet und ausgeführt wird, sobald diese gestartet ist.



PYAPP_DISTRIBUTION_EMBED ist ebenfalls wichtig: Wird eine PyApp Binary erstellt, wird die für die Execution erforderliche Python-Distribution beim ersten Start aus dem Netz geladen. Wenn Sie diese Variable auf 1 setzen, bindet PyApp die erforderliche Python-Distribution vorab in die generierte Binärdatei ein. Das Ergebnis ist eine größere Binary, die allerdings nichts mehr herunterladen muss. Sie ist in der Lage, sich selbst zu entpacken.




Darüber hinaus stehen diverse weitere Optionen zur Verfügung. Die genannten sollten aber für die meisten gängigen Projekte ausreichen. Um sich die Arbeit zu erleichtern, können Sie für jedes Projekt ein Shell-Skript erstellen, das diese Umgebungsvariablen einrichtet und den Kompilierungsprozess ausführt.



PyApp-Binärdatei erstellen



Nachdem Sie die Umgebungsvariablen festgelegt haben, wechseln Sie zum Stammverzeichnis des PyApp-Quellcodes und erstellen PyApp mit dem Rust-Compiler und folgendem Befehl:





cargo build --release






Das kann einige Minuten dauern, weil die Utility viele Abhängigkeiten aufweist (zum Zeitpunkt der Erstellung dieses Artikels ganze 363). Nachdem Rust alles abgerufen und zwischengespeichert hat, sollten zukünftige Kompilierungsdurchläufe jedoch deutlich weniger Zeit in Anspruch nehmen. Eine Cross-Kompilierung für andere Plattformen ist zwar grundsätzlich möglich, wird jedoch weder empfohlen noch unterstützt.



Nach Abschluss der Kompilierung befindet sich die resultierende Binärdatei im Unterverzeichnis target/release des PyApp-Projektverzeichnisses – als pyapp.exe. Diese Datei können Sie auch beliebig umbenennen, solange sie weiterhin ein Executable bleibt.



PyApp Binary ausführen



Um die Binary zu testen, führen Sie sie einfach über eine Konsole aus. Wenn alles in Ordnung ist, sollten Sie hier auch Prompts zu sehen bekommen, während PyApp sich selbst entpackt und für die Ausführung vorbereitet. Sollten Ihnen innerhalb der Konsole Fehler auffallen, notieren Sie diese und bearbeiten Ihre Umgebungsvariablen entsprechend. Mögliche Fehlerquellen sind etwa falsch eingerichtete Entry Points oder Startskripte für das Projekt.



Wenn Sie steuern möchten, wo sich die PyApp-Binärdatei entpackt, können Sie dazu eine Umgebungsvariable definieren:





PYAPP_INSTALL_DIR_ = "path/to/directory"






Mit Blick auf diesen Code ist zu beachten, dass eine “Versalien-Version” von innerhalb der PYAPP_PROJECT_NAME-Variablen zum Einsatz kommt. Für das Programm conwaylife würden wir also den Variablennamen PYAPP_INSTALL_DIR_CONWAYLIFE verwenden. Das Verzeichnis kann sowohl ein vollständiger als auch ein relativer Pfad sein. Sie könnten also ein Verzeichnis wie ./app nutzen, um anzugeben, dass die Anwendung in das Unterverzeichnis app des aktuellen Arbeitsverzeichnisses entpackt werden soll.



Wichtig: Diese Einstellung ist nicht dauerhaft. Wenn Sie diese Umgebungsvariable beim Ausführen des Programms nicht genau so definiert haben, wird standardmäßig das user-profile-Verzeichnis verwendet.



PyApp-Optionen



Das resultierende PyApp-Executable enthält praktische Befehle:




pyapp self remove entfernt die entpackte App aus dem Verzeichnis, in das sie entpackt wurde.



pyapp self restore entfernt die App und installiert sie neu.




Ein letzter Hinweis: Mit PyApp gepackte Python-Apps lösen unter Windows möglicherweise falsche Alerts bei Antivirus-Lösungen aus. Das liegt daran, dass die so erstelleten .exe-Dateien standardmäßig nicht mit Code signiert sind. (fm)

Reason

Reason ist ein Musik-Programm, mit dem Sie Beats, Mashups und ganz eigene Songs erstellen können.

mehr ...