The problem Link to heading

You have a Python application spread across several files and you want to ship everything as a single file. What if you could package it into a .zip and run it with python app.zip?

The tip Link to heading

You can, and it is simpler than it looks. Python knows how to execute a .zip directly, as long as there is a __main__.py inside it. Let’s start from scratch.

Create a __main__.py file:

print("Hello, world!")

Now zip it up:

zip app.zip __main__.py

And run it:

python app.zip

Output: Hello, world!. The .zip became executable, without unpacking anything.

Why it works Link to heading

When you point Python at a folder or a .zip, it looks for a __main__.py inside and runs that file as the entry point. It is the same __main__ you get when you run python -m package: the name Python looks for to know where to start. Without that file, it complains that it could not find an entry point.

With any application Link to heading

For a real application, with several modules, building the zip by hand is tedious. The built-in zipapp module does it for you. You have a myapp folder with your code and you only need to say which function is the entry point:

python -m zipapp myapp -m "cli:main"

That generates a myapp.pyz (an executable zip) with a ready-made __main__.py inside, which only does:

import cli
cli.main()

Then it is just python myapp.pyz and your whole application runs from a single file.

You can even include your dependencies in the zip, just install them inside the folder before packaging (pip install -r requirements.txt --target myapp). This only works for pure Python packages: C extensions do not run from inside the zip and need to be installed separately.

Want to run it without python in front, just ./myapp.pyz? Generate the .pyz with -p "/usr/bin/env python3" and chmod +x it.

That’s it, folks!

See you next time!

{}’s