Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python zipapp: build an executable archive without bundling an interpreter

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A zipapp is a ZIP archive with a Python entrypoint that a compatible interpreter can execute as an application.

Download Python source kit

Operation contract

The fixture writes one owned __main__.py module, builds a compressed archive and executes it in a child interpreter with explicit arguments. The subprocess checks its exit code and expected output. The archive is deleted with its temporary directory and is not published to a package registry.

Failure and ownership boundary

The archive does not contain Python itself, and third-party/native extension dependencies need a separate distribution strategy. A .pyz file is executable code, not a safe data document to inspect by running it. The example uses only source it just wrote. Python package layout: owned imports and module entrypoints and Python subprocess: argument vectors, exit codes and bounded fixtures explain the surrounding behavior.

Working program

python
from pathlib import Path
import subprocess
import sys
import tempfile
import zipapp
from zipfile import ZipFile

with tempfile.TemporaryDirectory() as directory:
    application = Path(directory) / "receipt_cli"
    application.mkdir()
    (application / "__main__.py").write_text(
        'import sys\n'
        'if len(sys.argv) != 2 or sys.argv[1] != "--region-count":\n'
        '    raise SystemExit(2)\n'
        'print("supported regions: 2")\n', encoding="utf-8")
    archive = Path(directory) / "receipt_cli.pyz"
    zipapp.create_archive(application, archive, compressed=True)
    result = subprocess.run([sys.executable, "-I", str(archive), "--region-count"],
                            cwd=directory, capture_output=True, text=True, timeout=5, check=True)
    print(result.stdout.strip())
    with ZipFile(archive) as built:
        print("archive built:", "__main__.py" in built.namelist())

Output

Output
supported regions: 2
archive built: True

Costs and limits

Archive creation scans and compresses supplied files; storage depends on their contents. Runtime imports may decompress source. This fixture has tiny fixed output and does not enforce a general child-output/process-tree budget.

Common Mistakes

  • A zipapp needs a compatible external interpreter.
  • Do not execute an untrusted archive merely to identify its format.

Connected lessons

Python package layout: owned imports and module entrypoints, Python subprocess: argument vectors, exit codes and bounded fixtures, Python package resources: read data from a ZIP-backed package.

python
zipapp-distribution
Storage details