My application looks like this:

main.py
windows/
    __init__.py
    mainwindow.py
    ...
model/
    __init__.py
    orders.py
    ...
resources/
    image1.png
    logo.jpg
    ...

The program is started with main.py. Is there a good way to create a ‘final’ application out of it? I’m thinking of something like py2exe/py2app, but without copying the python interpreter / modules into the application where one has only one executable.

I had a look at distutils, but this looks like it installs a program into the Python directory, which isn’t usual on non-linux platforms.

At the moment I just copy the whole source folder onto the target machine and create an alias to main.pyw on windows. Some inconveniences:

  • The icon is the default python icon.
  • I have to create the alias manually.
  • In my source directory there are a lot of additional files like the source control folder.
  • I have to rename main.py to main.pyw manually.
  • It would be nice if only `.pyo* files are on the target machine. There’s no real reason for it, I just don’t like having unnecessary files.

How does one create a nice automated distribution?

  • for windows? (That’s the only platform that I have to support at the moment.)
  • for mac?
  • for linux?

I highly recommend Pyinstaller, which supports all major platforms pretty seamlessly. Like py2exe and py2app, it produces a standard executable on Windows and an app bundle on OS X, but has the benefit of also doing a fantastic job of auto-resolving common dependencies and including them without extra configuration tweaks.

Also note that if you’re deploying Python 2.6 to Windows, you should apply this patch to Pyinstaller trunk.

You indicated that you don’t need an installer, but Inno Setup is an easy to use and quick to setup choice for the Windows platform.

The normal way of distributing Python applications is with distutils. It’s made both for distributing library type python modules, and python applications, although I don’t know how it works on Windows. You would on Windows have to install Python separately if you use distutils, in any case.

I’d probably recommend that you distribute it with disutils for Linux, and Py2exe or something similar for Windows. For OS X I don’t know. If it’s an end user application you would probably want an disk image type of thing, I don’t know how to do that. But read this post for more information on the user experience of it. For an application made for programmers you are probably OK with a distutils type install on OS X too.

I think it’s also worth mentioning PEX (considering more the attention this question received and less the question itself). According to its own description:

PEX files are self-contained executable Python virtual environments. More specifically, they are carefully constructed zip files with a #!/usr/bin/env python and special __main__.py that allows you to interact with the PEX runtime. For more information about zip applications, see PEP 441.

I stumbled upon it when I read an overview of packaging for python. They posted this nice picture there:
enter image description here

To summarize: If you can afford relying on python being installed on the target machine, use PEX to produce a self-containing »executable« which probably will have smaller file size than an executable produced by PyInstaller, for example.

Fredrik Lundh’s squeeze.py can create a single file that does not contain the Python interpreter, but instead contains bytecode. With the right arguments, you can include other files, modules, etc. in the result file. I used it successfully in one project. The resulting program ran on OS X, Linux and Windows without any problem!

PS: Each machine needs to have a Python interpreter which is compatible with the bytecode generated by squeeze.py. You can generate different bytecode versions for different versions of Python, if need be (just run squeeze.py with the right version of Python).

I think IronPython has a built in compiler for windows:

I tried out Cx_Freeze and think it is by far the best .py to .exe (plus a few .dlls) compiler I’ve ever used.

If you are distributing on windows, use an installer to install all the relevant files/interpeter whatever is needed. Distribute a setup.exe. That is the best way on windows. Otherwise users will complain.

The most convenient* cross-platform way of distributing python desktop applications is to rely on cross-platform conda package manager. There are several tools that use it:

  • Miniconda-Install – powershell/bash scripts that auto-download Miniconda and create isolated conda environment for the app. Supports pip but seem to be unmaintained and has https download issues.
  • Anaconda Project and (conda) constructor by Continuum. Both use conda. (conda) constructor seem to be able to create self-contained installers and even NSIS installer on Windows but doesn’t support pip. Seem to behave like Anaconda/Miniconda installers.
  • PyAppShare – the end-user installs Miniconda/Anaconda first (like a runtime environment). Then single install batch/bash script creates isolated conda environment from yaml spec. The application is also a conda/pip package itself that is installed to environment and an executable entry point is created. Cross-platform Desktop and Programs shortcuts automatically created. They activate environment and start the application. Supports pip.

* The most convenient for the developer. Enough convenient for the end-user.

For Windows, I found py2exe extremely easy to use.

pip install distutils
pip install py2exe

All it takes is a few lines of code in setup.py:

from distutils.core import setup
import py2exe

setup(console=['hello.py'])

Py2exe builds an executable and includes all dependencies. You may need to manually add the C++ runtime before building the exe:

from glob import glob
data_files = [("Microsoft.VC90.CRT", glob(r'C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT\*.*'))]
setup(
    data_files=data_files,
    ...
)

https://py2exe.org has a nice and simple tutorial that’s about 3 pages long.