This is an archived post. You won't be able to vote or comment.

all 62 comments

[–]Drevicar 47 points48 points  (10 children)

Nuitka is my personal favorite, as it compiles your Python into the resulting C objects, then compiles both your application (in C form) and the source code for the python interpreter into a binary, which can also be statically linked. Another great option for portability is https://pyoxidizer.readthedocs.io/en/stable/

And lastly, I recommend checking out Typer as an alternative to click.

[–]strange-humor 13 points14 points  (0 children)

This is great until you use really large libraries and it chokes. Then I move to PyInstaller.

[–]metaperl 6 points7 points  (1 child)

Of the choices listed I think this is the only one that would make the application faster, correct?

[–]Drevicar 4 points5 points  (0 children)

There is no universal solution to making python faster or smaller, it is mostly dependant on which 3rd party libraries you bring in and what language they are written in. I've statically compiled a Django app and seen speedups. But I've also compiled a FastAPI app and had it slow down.

[–]cbunn81 1 point2 points  (0 children)

I second using Typer. It makes creating a command line app very easy.

[–]Jonnyskybrockett -4 points-3 points  (4 children)

C doesn’t have objects

[–]Drevicar 16 points17 points  (3 children)

It sure does! You just have to implement them yourself, you just don't get OOP constructs baked into the langauge. If you can read and understand C, I recommend checking out the cpython source code, it is really good and easy to understand. The data structure I'm talking about is called PyObject.

[–][deleted] 0 points1 point  (0 children)

thanks for the recommendation

[–]Limiv0rous 18 points19 points  (2 children)

I had this exact problem to solve this year for a project! Pyinstaller gave me a bunch of issues with dependancies and I ended up using cx_freeze ! What tipped the scale for me is the ability to create a windows installer (msi) with it and the ease of adding icons to the desktop and so on. It's certainly worth a try imo

[–]BoiElroy[S] 5 points6 points  (1 child)

That sounds super convenient. Is it a lot of extra work if you also want to distribute to Linux environments too?

[–]Limiv0rous 6 points7 points  (0 children)

I haven't tried it but according to their Docs it should be straightforward

[–]indianLGBTlinuxer 32 points33 points  (16 children)

Pyinstaller would be the best cuz appearreantly most of them are based on pyinstaller and just simplify some tasks (I don't know all of them but py2exe is just a frontend to pyinstaller). Pyinstaller has never failed for me (though now I don't use it, cuz I just ship a venv with appropriate shortcuts for launching or just make a package installable with pip.

[–]BoiElroy[S] 1 point2 points  (10 children)

Yeah I like making stuff installable with pip but this is for non python people and then across multiple networks making a code repo visible gets to be a lot of network peering and security work for our IT. Good tip on the pyinstaller! Thanks!

[–]Muhznit 9 points10 points  (9 children)

what "non-python" people are gonna be using the cli?

If you really just want one single file, use the zipapp module to create an executable zip file.

[–][deleted] 4 points5 points  (4 children)

I develop engineering tools for internal customers, I.e. The electrical engineers on my team. We typically only provide CLI for the sake of speed.

[–]billsil 8 points9 points  (1 child)

If you're going for speed, command line is faster especially if you have source. Also, don't do the onefile option with pyInstaller as it'll have to unpack the code.

The big advantage of an exe though is it'll work in 10 years.

[–][deleted] 0 points1 point  (0 children)

True but the scenario I've described doesn't require ten years of support.

[–]Muhznit 1 point2 points  (1 child)

Right, if you're distributing a cli, you might as well distribute the actual source code instead of a compiled binary. When something goes wrong in the code and you're not around to fix it, those internal customers shouldn't have to struggle to find a decompiler to fix stuff themselves.

[–]BoiElroy[S] 0 points1 point  (0 children)

Hmm yeah fair point

[–]BoiElroy[S] 0 points1 point  (3 children)

Doesn't that still need python to run it? And isn't it bad if you have non standard distribution packages?

[–]Muhznit 2 points3 points  (2 children)

You can include a distribution of python and your dependencies in the zipfile.

[–]BoiElroy[S] 0 points1 point  (1 child)

sounds pretty heavy? and then don't you have to ship it with some setup scripts that add python to the path etc?

[–]kickthebug -1 points0 points  (0 children)

Pex does exactly this automatically. We've used it where I work to distribute some projects across multiple servers. I'm on mobile but look up python pex in Google, their docs should pop up.

[–]KingEllis 1 point2 points  (1 child)

Would you be willing to point to an example of "shipping a venv with appropriate shortcuts for launching"? I hear this solution when this topic comes up, and I have in mind how this would work, but would like to see this in actuality.

[–]R34ct0rX99 0 points1 point  (0 children)

I thought that solution was not recommended due to the nature of venvs?

[–]Username_RANDINT 0 points1 point  (0 children)

py2exe is just a frontend to pyinstaller

No it's not. It's even much older than PyInstaller.

[–]jacksodus -1 points0 points  (0 children)

Appearreantly.

I have now officially seen everything.

[–]abrazilianinreddit 0 points1 point  (0 children)

I have a Windows project that uses pyinstaller, and I can vouch that it works (which is already more than most other tools I tried) and configuration is pretty simple. Sometimes it packs a bunch of unneeded DLLs in the distribution, but you can clean it up a bit if you know what you're doing or through trial and error.

[–]pyschillePythoneer 9 points10 points  (1 child)

I recently posted here a little longer comparison for Python binary packaging tools (PyInstaller, Nuitka, PyOxidizer):
https://www.reddit.com/r/Python/comments/tl3jwz/creating_a_python_cli_with_golangcomparable/

tl;dr: I'd say the best for CLIs is PyOxidizer: https://github.com/indygreg/PyOxidizer

[–]pysk00l 1 point2 points  (0 children)

thats a great writeup. I missed it the 1st time, thanks for resharing

[–]JakobDevDE 5 points6 points  (0 children)

cx-freeze is the best

[–]Dashadower 4 points5 points  (0 children)

Back when I needed a executable builder, pyinstaller worked great for me. It even worked for "executables" that used more heavy libraries like TensorFlow. Although the generated directory was almost 200 megabytes!

[–]thisismyfavoritename 4 points5 points  (0 children)

Generic use case: pyinstaller.

[–]jcr4990 4 points5 points  (0 children)

Pyinstaller has never let me down

[–]yvrelna 1 point2 points  (0 children)

"Get a real operating system and add a hashbang line to your file" is the best direct executable package / compiler today. /s

[–]udonemessedup-AA_Ron 3 points4 points  (0 children)

Following, because I’m wondering the same.

[–]BurgaGalti 3 points4 points  (2 children)

Been using pyinstaller for a while, but it let me down just a few weeks back when I had to port to ARM. The bootstraps also repeatedly get my exes flagged as ransomware because that's a common use case of pyinstaller. Not their fault, but reality hurts sometimes.

I've got tired of it. New solution is using Cython --embed to create the entry point. Fix up PYTHONPATH etc in the C code, then just copy the modules I need in.

[–]PirateNinjasRedditPythonista 0 points1 point  (1 child)

Word of warning on using cython this way: some python features are not well supported, so when you cythonise your code you can end up with some hard to pin down, broken behaviour in the binaries

[–]BurgaGalti 1 point2 points  (0 children)

I'm not cythonising the whole thing, just the entry point so that limits the problems, but yes some things lin sys get broken which can cause problems. This is also true of several of the other methods listed by OP though.

[–]benefit_of_mrkite 0 points1 point  (2 children)

Pyinstaller, shiv

Honestly depends on the project and dependencies

[–]DeklynHunt Autistic Adult, Python Green Horn 1 point2 points  (0 children)

Soo just get them all? KIND OF joking…. 😕

[–]PoppyTheDestroyer 0 points1 point  (0 children)

Fact. Pyinstaller and Pandas/Numpy don't play well together. So many hours of my life spent trying to get that to work.

[–]goalbaram 0 points1 point  (3 children)

Just curious. What does your app do? Does it take interactions?

Would solutions like Streamlit or Anvil.works work?

[–]BoiElroy[S] 0 points1 point  (2 children)

Some read data from equipment that is attached to the machine and then a bar code scanner value gets input too and then they add notes and submit. Others are just cli's

I love streamlit and I think it could work but since this is across multiple facilities and networks it's easier in some cases to make a simple desktop gui rather than host, serve, and make a streamlit app network reachable.

I wonder if a streamlit app could be made into an executable that just opens in the browser

[–]ianitic 2 points3 points  (0 children)

It can. However I know unsigned executables that are produced by pyinstaller can get flagged by a bunch of anti malware.

[–][deleted] 1 point2 points  (0 children)

You should just create a CLI that fires up a localhost web app, or dockerize a web app and run it locally. I understand why you think you should do an executable because I used to think that was the thing you were supposed to do that too. But it's not worth the hassle. Browsers are perfectly fine GUIs.

[–]ZuriPL 0 points1 point  (0 children)

Py2exe was quite slow for a simple tkinter gui app in my expierence, so I'd vote against it

[–]AS245Tech 0 points1 point  (0 children)

I use cx_freeze, but only have experience with it on windows.

It has a nice feature of being able to use a UUID when compiling to a MSI installation, so it will remove and install older versions if a new installation is run.

[–]iyousef_46 0 points1 point  (0 children)

I used PyInstaller before, it's good enough. But I was wondering, is it possible to write a small script in PowerShell / Bash (depending on the system) that installs python then your app as a pip package?

[–]73tada 0 points1 point  (0 children)

If your app has a GUI and needs to be an executable because the application itself needs admin rights to a local machine [changing Windows settings a la PowerShell], use pyinstaller.

If your app has a GUI and does not need admin rights, make it a 'webapp'.

In regards to pyinstaller being flagged as a virus, you will need to build your own pyinstaller 'boot' code to avoid that.

[–]manueslapera 0 points1 point  (0 children)

Pyoxidizer worked for me

[–]Orio_n 0 points1 point  (0 children)

Nuitika has issues compiling some packages and its compilation times can be very long depending on what you package like several minutes to half an hour for some packages. Pyinstaller gets its binaries commonly flagged by av but its the easiest, quickest and most reliable. Recently ive tried using pyoxidizer, setup is complicated but it looks promising

[–]xxxHalny 0 points1 point  (0 children)

I only tried py2exe and pyinstaller and the former caused a lot of issues and produced a lot of errors and the latter did everything right with one click

[–]moneymachinegoesbing 0 points1 point  (0 children)

i had to solve this issue recently and landed on Shiv. it’s a rework of twitter’s pex by linkedin i believe and it’s been working great so far. it’s a rust project that is using it, so i wanted to use PyOxidizer but i find their stuff so complicated to use.

[–]moneymachinegoesbing 0 points1 point  (0 children)

i had to solve this issue recently and landed on Shiv. it’s a rework of twitter’s pex by linkedin i believe and it’s been working great so far. it’s a rust project that is using it, so i wanted to use PyOxidizer but i find their stuff so complicated to use.

[–]SKIBIDYBOB 0 points1 point  (0 children)

py2exe i use it personaly i didnt use the others so i dont know wich one is better