0

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?

sinoroc
  • 18,409
  • 2
  • 39
  • 70
Psionman
  • 3,084
  • 1
  • 32
  • 65
  • I recommend to try [*pex*](https://pypi.org/project/pex/) and [*shiv*](https://pypi.org/project/shiv/). These tools will help you build *zipapps*. I also built [*zapp*](https://pypi.org/project/zapp/) for my own usage, it has worked well for my very simple needs. -- But anyway it should work without all these. -- You need to provide the details of what you tried. How did you build your *zipapp*? Which commands did you use? If possible, provide a [mre]. -- Reminder that StackOverflow is not for individual support though. It's a Q&A community, and you do not have a question. – sinoroc Apr 15 '23 at 18:41

2 Answers2

2

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.

sinoroc
  • 18,409
  • 2
  • 39
  • 70
  • That's exactly what I wanted - the missing link for me was "python -m pip install termcolor --target build". Now termcolor does not work on windows (wrong encoding I think)... but that's another problem – Psionman Apr 16 '23 at 10:55
  • 1
    Should anyone be wondering: termcolor on windows requires colorama (see [this answer](https://stackoverflow.com/questions/21858567/why-does-termcolor-output-control-characters-instead-of-colored-text-in-the-wind)) – Psionman Apr 16 '23 at 11:31
0

The inclusion of dependencies that are not incorporated within the standard Python installation into a Python zip archive is an entirely plausible feat. This can be achieved by means of a tool such as PyInstaller or cx_Freeze, both of which are capable of generating a self-contained executable file comprising all of the necessary dependencies.

The initial step to harnessing the power of PyInstaller or cx_Freeze is to craft a requirements.txt file, which is essentially a rundown of all the dependencies that your application necessitates, inclusive of termcolor. This can either be manually generated or automatically generated with the assistance of a tool like pipreqs, which scours your code's import statements to identify required dependencies.

Upon the successful creation of the requirements.txt file, the next step is to utilize either PyInstaller or cx_Freeze to generate the executable file. Both of these tools offer the ability to specify a requirements file, thereby permitting the automatic downloading and inclusion of all required packages in the executable.

Here is an example command to create an executable file utilizing PyInstaller:

pyinstaller --onefile --add-data "path/to/requirements.txt;." myscript.py

Upon executing this command, a solitary executable file shall be created, located in the dist folder, and shall include both your Python script (myscript.py) and the requirements.txt file. Upon its execution on a Windows machine, the executable shall automatically install the required dependencies and execute your script.

In the same vein, here is an example command to create an executable file utilizing cx_Freeze:

cxfreeze myscript.py --include-path=path/to/requirements.txt

Executing this command shall generate an executable file, located in the build folder, that includes both your Python script and the required dependencies as stipulated in the requirements.txt file.

Take note that PyInstaller and cx_Freeze offer additional options and settings that can be used to tailor the executable's behavior according to your needs. It is advisable to peruse the documentation for each tool thoroughly to gain a more profound comprehension of their capabilities.

iHunter
  • 3
  • 3