Python Desktop application distribution

I’m currently working on a Python desktop application and I’ve run into a bit of a problem. I’ve tried using PyInstaller to package my application, but it seems to only work on my development machine which runs Ubuntu 20. However, my aim is to make the application run on all Linux systems.

I’ve also tried using fpm to create deb and rpm packages, but I’m a bit lost since I don’t have any experience using it. So I’m wondering if there’s another way to package my Python application that will make it easily distributable across all Linux systems.

I would really appreciate any suggestions or advice on how to solve this problem. Thank you in advance for your help!

What does that mean? Have you tried on other environments than Ubuntu 20? What happened there? Any error message?

What is fpm?

Maybe we need to be on the same page regarding what you want to achieve (and on the vocabulary). I suggest we use the following document as initial reference: Overview of Python Packaging - Python Packaging User Guide .

if you mean to rebuild the app on another environment, I assume it would run for that environment’s OS, I have made a little search and asked GPT about how py installer works, and the answer is that it uses the build the application for users that are using OSs as development machine in my case (Ubuntu 20). it would be so hard to build my app on all environments.
FPM is a tool that can be used to build both .deb and .rpm at the same usage but I have no experience with it fpm link
and thanks for your reference I will read it and if you have another suggestion please tell me

If you want us to be able to help you, you really need to explain how the app is failing, like what error message you’re getting. There are zillions of ways in which it could fail. It’s impossible to guess without more details.

1 Like

By the way: packaging an app with Python from Ubuntu 20.04 won’t make it run on all Linux systems, since the Python executable embedded in the app is compiled against the glibc version from Ubuntu 20.04. However, AFAIK, it should normally make it compatible with all systems with a later glibc version, which means most recent Linux systems.

Sorry for not making the error clear here is what happens but let me explain what the application does:
The application it’s first screen when it opens shows a “welcome page” When the user clicks next he moves to the next page which is taking an “id” Then depending on that id an exam link will be opened in a new window as a browser, that opens the exam in the desktop application as it was a browser but modified because it is a proctoring app in general.
Here is the problem:
as I mentioned on Ubuntu 20 there are no problems since the new machine is the same as my development machine. But for Mint OS the program runs and when it comes to the screen whose function is to open the exam as a browser it shows a white screen and then the app crashes.

OK, with that info I would not put “packaging issue” as my first guess. Why do you think it is a packaging issue? Typically if an application installs and starts correctly but only later crashes at run-time, then I would not necessarily investigate packaging first. Additionally, as far as I know, Mint is basically Ubuntu with another name, so I would expect that if something runs fine on Ubuntu it will run fine without modification on Mint as well. So, again why do you think it is an issue with packaging or Pyinstaller?

Is there any kind of error message or stack trace printed somewhere at the moment of the crash? If yes, I recommend you copy this full error message here, if you want someone to be able to help you.

Can you run the application from a terminal? Then you should be able to see the traceback that’s printed when the app crashes.

I am not sure about the package issue but what made me think of it because my team mate made the executable on windows and it worked fine with no issues, also i just tried it again now and the log file of the application runs correct in the same flow when it comes to state “open browser” it stopes and no logs comes again because the app stopped, and no errors in the log file

i did that, it shows no errors as well, however i read something related to OpenGl, does this make a problem ? i will get the full error and the log file and show you here, also os it would be the problem because of the system is new and i run the application on a bootable drive but if so why it worked on boot ubuntu drive and not this one !?

here is the mint os test application log file link

terminal test link

@sinoroc @jeanas

OK, lots of error there… not sure it is even related Python at this point. Maybe something with Qt. No idea. I think I’m out.

“libGL error: MESA-LOADER: failed to open iris: /usr/lib/dri/iris_dri.so: cannot open shared object file: No such file or directory (search paths /usr/lib/x86_64-linux-gnu/dri:$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)” looks like the program tried to find a dynamic library on a path installed by a system package (libgl1-mesa-dri) on your Ubuntu system, which won’t work if the package is not installed on the other machine, or if the other machine’s package manager put the dynamic library in a different location.

First, this sounds like you have installed PyQt through your system package manager (something like sudo apt install python3-pyqt5). I’m not sure PyInstaller is designed to work well in this case. Essentially, PyInstaller will try to locate all your dependencies and bundle them, but the system could install them differently than standard Python tools, confusing PyInstaller. So, I would try to create a virtual environment…

… and pip install pyqt5 (or pyqt6, or pyqt4, depending on what you’re using for the GUI), within the virtual environment, then run PyInstaller from there.

pip will install PyQt from PyPI (PyQt5 · PyPI), which provides self-contained PyQt5 binaries with a more standard layout (the wheel format) than what your Linux distribution provides.

If that doesn’t solve it, I would ask on a PyInstaller-specific place.

If your package is in pure python, a pure python wheel will be good enough. Python is usually available on Linux distributions, so there is no need to distribute a python interpreter by yourself (which PyInstaller does). if there are some C extensions in your package, manylinux wheels can be helpful.

If you really want to distribute all dependencies including cpython and pyqt, Flatpak or AppImage could be better than PyInstaller.

flatpak and appimage are well suited for linux. what about windows and mac?

what we would simply need for simply pure-python application is to be able to distribute a dependency frozen wheel in python. Yes that would mean our application cannot be installed in a shared virtualenv and would require to use pipx for instance, but it means that the end user will get the same application and dependencies combination than what has been carefully validated by the ci.

Zipapp/shiv works fine for these use case, but cannot be distribued through pypi and requires another storage.

There is a bunch of things here: Overview of Python Packaging - Python Packaging User Guide

Maybe you are in the “Bringing your own Python executable” case.

Thanks. I intensively used pyinstaller and other tools to deploy our internal set of tools (mostly for proprietary CI) and i now use and recommend the following combination:

  • poetry to maintain the lockfile (the lockfile is actually neccessary for freezing the dependencies for end user but also for the developmer itself)
  • shiv to package the frozen dependencies without enbedding the python (this leads to os-dependent executable and cross compilation is a nightmare, leading to lot of additional source of errors). shiv generates a os-agnostic zipapp and is enough for 99% of our use cases.
  • pyinstaller is great, love it. i only have 1 project i have to maintain it, but it is really hard to maintain overtime (even if it is a lot simpler now). for pure-python app, shiv does a great job.

But:

  • zipapp does not have a distribution channel. pypi does not accept it, so we need to store them in a file repository, so we do not have a "package management style installation: how would do a pipx install mywonderfulapp>2 with zipapp/pex?
  • same for pyinstaller/pyoxdyzer and so on. now way to distributes these package with pypi or any other repository management supported by artifactory (our fileserver).

the thing is not really to build python application, but to standardize how they would be distributed.

On Windows? Scoop, winget, Chocolatey, Windows Store?

Before all that and still today Windows always has been about downloading random executable installers from random websites.

1 Like

yes, but you have 1 way for windows, one for linux, one for mac… but you already have pypi everywhere !

It is a well known fact that the Python packaging ecosystem (the PyPA-based one: pip, PyPI, wheels, and so on), is quite good at handling libraries but quite bad at handling applications. One way one could interpret that is that the PyPA ecosystem is for Python developers; not for end users of the applications written in Python. It is not that simple of course, but maybe it helps with setting the right expectations.

Not that the PyPA ecosystem does not want to handle applications, but it is just not there yet. There are some improvements being made that might help us get there soon-ish. From my point of view an example of one important piece missing is the creation of a standard lock file format.

I am pretty sure the things you are looking for have been discussed already (for example distributing zipapps on PyPI or a PyPI-like repository where pipx or a pipx-like tool can install from), and as far as I can recall there were no objections against those ideas, it is just that they have not happened yet, no one has had the time to write the PEPs, draw the plans, code the implementations, and so on…

Anyway…

From what I read in your messages: wouldn’t a wheel with pinned dependency version constraints work for your use case? This would be pipx-installable, right?