pythonpython-packagingzipapp

Can I create an executable Python zip archive with dependencies?


I have a small python application developed on Nix that I wish to distribute to some M$ Windows users. It seems that an executable Python zip archive is an excellent way to achieve this.

However, I would like to include dependencies that are not included with the standard Python installation, e.g. termcolor. Is this possible?

This is the app that I am testing

from termcolor import cprint

print('hello world')
cprint('hola mundo', 'red')

and termcolor is not included in the standard Python implementation. I do not expect the users to pip install.

I have built a .pyz using

 python  -m zipapp . -o my_app.pyz

and the app is created and it works in a virtualenv with termcolor installed. But of course fails if it is not.

I have also tried

python  -m zipapps my_app -o my_app.pyz -r requirements.txt

This creates a .pyz which includes termcolor, but when I run it, it drops into the Python REPL

Is this possible?


Solution

  • You need to provide the --main option. It is best done by creating a main function first.

    my_app.py

    from termcolor import cprint
    
    def my_main():
        print('hello world')
        cprint('hola mundo', 'red')
    
    if __name__ == '__main__':
        my_main()
    

    And then package with something like that:

    mkdir build
    mkdir dist
    python -m pip install termcolor --target build
    cp my_app.py build
    python -m zipapp build --main my_app:my_main --output dist/my_app.pyz
    

    Finally this can be run with:

    python dist/my_app.pyz
    

    And this .pyz file can be moved anywhere (on the same machine) and it will continue to work, as it includes the dependencies (no need for virtual environment). If the dependencies are pure Python only (as it seems to be the case for termcolor), then the .pyz file can be used with other Python interpreter versions and on other operating systems.

    Optionally you can also set a shebang with the --python option.


    Anyway, if then later you aim for more serious usage, I recommend using pex or shiv for this. These tools will take care of handling many complex corner cases.