How can I distribute python programs?

Viewed 92399

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?
8 Answers

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.

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.

Related