Python's zipapp: Build Executable Zip Applications

Python's zipapp: Build Executable Zip Applications

by Leodanis Pozo Ramos intermediate python tools

A Python Zip application is a quick and cool option for you to bundle and distribute an executable application in a single ready-to-run file, which will make your end users’ experience more pleasant. If you want to learn about Python applications and how to create them using zipapp from the standard library, then this tutorial is for you.

You’ll be able to create Python Zip applications as a quick and accessible way to distribute your software products to your end users and clients.

In this tutorial, you’ll learn:

  • What a Python Zip application is
  • How Zip applications work internally
  • How to build Python Zip applications with zipapp
  • What standalone Python Zip apps are and how to create them
  • How to create Python Zip apps manually using command-line tools

You’ll also learn about a few third-party libraries for creating Zip applications that overcome some limitations of zipapp.

To better understand this tutorial, you need to know how to structure Python application layouts, run Python scripts, build Python packages, work with Python virtual environments, and install and manage dependencies with pip. You also need to be comfortable using the command line or terminal.

Getting Started With Python Zip Applications

One of the most challenging problems in the Python ecosystem is finding an effective way to distribute executable applications, such as graphical user interface (GUI) and command-line interface (CLI) programs.

Compiled programming languages, such as C, C++, and Go, can generate executable files that you can run directly on different operating systems and architectures. This ability makes it easy for you to distribute software to your end users.

However, Python doesn’t work like that. Python is an interpreted language, which means that you need a suitable Python interpreter to run your applications. There’s no direct way to generate a standalone executable file that doesn’t need an interpreter to run.

There are many solutions out there that aim to solve this issue. You’ll find tools such as PyInstaller, py2exe, py2app, Nuitka, and more. Those tools allow you to create self-contained executable applications that you can distribute to your end users. However, setting these tools up can be a complex and challenging process.

Sometimes you don’t need that extra complexity. You just need to build an executable app from a script or a small program so that you can distribute it to your end users quickly. If your application is small enough and uses pure Python code, then you can be well-served with a Python Zip application.

What Is a Python Zip Application?

PEP 441 – Improving Python ZIP Application Support formalized the idea, terminology, and specification around Python Zip applications. This type of application consists of a single file that uses the ZIP file format and contains code that Python can execute as a program. These applications rely on Python’s ability to run code from ZIP files that have a __main__.py module at their root, which works as an entry-point script.

Python has been able to run scripts from ZIP files since versions 2.6 and 3.0. The steps to achieve that are pretty straightforward. You just need a ZIP file with a __main__.py module at its root. You can then pass that file to Python, which adds it to sys.path and executes __main__.py as a program. Having the application’s archive in sys.path allows you to access its code through Python’s import system.

As a quick example of how all that works, say you’re on a Unix-like operating system, such as Linux or macOS, and you run the following commands:

Shell
$ echo 'print("Hello, World!")' > __main__.py

$ zip hello.zip __main__.py
  adding: __main__.py (stored 0%)

$ python ./hello.zip
Hello, World!

You use the echo command to create a __main__.py file containing the code print("Hello, World!"). Then you use the zip command to archive __main__.py into hello.zip. Once you’ve done that, you can run hello.zip as a program by passing the filename as an argument to the python command.

To round up the internal structure of Python Zip applications, you need a way to tell the operating system how to execute them. The ZIP file format allows you to prepend arbitrary data at the beginning of a ZIP archive. Python Zip applications take advantage of that feature to include a standard Unix shebang line in the application’s archive:

#!/usr/bin/env python3

On Unix systems, this line tells the operating system which program to use for executing the file at hand so that you can run the file directly without the python command. On Windows systems, the Python launcher properly understands the shebang line and runs the Zip application for you.

Even with a shebang line, you can always execute a Python Zip application by passing the application’s filename as an argument to the python command.

In summary, to build a Python Zip application, you need:

  • An archive that uses the standard ZIP file format and contains a __main__.py module at its root
  • An optional shebang line that specifies the appropriate Python interpreter to run the application

Besides the __main__.py module, your application’s ZIP file can contain Python modules and packages and any other arbitrary files. However, only .py, .pyc, and .pyo files are available for direct use through the import system. In other words, you can pack .pyd, .so, and .dll files in your application’s file but you won’t be able to use them unless you unzip them into your file system.

PEP 441 proposed .pyz and .pyzw as file extensions for Python Zip applications. The .pyz extension identifies console or command-line applications, while the .pyzw extension refers to windowed or GUI applications.

On Unix systems, you can remove the .pyz extension if you prefer a plain command name for your CLI applications. On Windows, the .pyz and .pyzw files are executable files because the Python interpreter registers them as such.

Why Use Python Zip Applications?

Say you have a program that your team uses a lot for their internal workflow. The program has grown beyond a single-file script into a full-fledged application with multiple packages, modules, and files.

At this point, some team members struggle to install and set up every new version. They keep asking you for a faster and easier way to set up and run the program. In that situation, you should consider creating a Python Zip application to bundle your program into a single file and distribute it as a ready-to-run app to your coworkers.

Python Zip applications are an excellent option for publishing software that you must distribute as a single executable file. It’s also a handy way to distribute software using informal channels, such as sending it through a computer network or hosting it on an FTP server.

Python Zip applications are convenient and quick ways to package and distribute Python applications in a ready-to-run format that can make your end user’s life much more pleasant.

How Do I Build a Python Zip Application?

As you’ve already learned, a Python Zip application consists of a standard ZIP file containing a __main__.py module, which works as the application’s entry point. When you run the application, Python automatically adds its container (the ZIP file itself) to sys.path so that __main__.py can import objects from the modules and packages shaping the application.

To build a Python Zip application, you can run the following general steps:

  1. Create the application’s source directory containing a __main__.py module.
  2. Zip the application’s source directory.
  3. Add an optional Unix shebang line to define the interpreter for running the application.
  4. Make the application’s ZIP file executable. This step applies to Unix-like operating systems only.

These steps are pretty straightforward and quick to run. With them, you can build a Python Zip application manually in a couple of minutes if you have the required tools and knowledge. However, the Python standard library includes a more convenient and faster solution for you.

PEP 441 proposed the addition of a new module called zipapp to the standard library. This module facilitates the creation of Zip applications, and it’s been available since Python 3.5.

In this tutorial, you’ll focus on creating Python Zip applications using zipapp. However, you’ll also learn how to run the whole series of steps manually using different tools. This additional knowledge can help you understand the entire process of creating Python Zip applications more deeply. It’ll also be helpful if you’re using a Python version lower than 3.5.

Setting Up a Python Zip Application

Up to this point, you’ve learned what Python Zip applications are, how to structure them, why to use them, and what steps you need to follow when creating them. You’re ready to start building your own. First, though, you need to have a functional application or script to use for your Python Zip app.

For this tutorial, you’ll use a sample application called reader, which is a minimal web feed reader that reads the latest articles and resources from the Real Python feed.

To follow along, you should clone the repository of reader into your local machine. Open your command line in a working directory of your choice and run the following command:

Shell
$ git clone https://github.com/realpython/reader.git

This command downloads the full contents of the reader repository into a reader/ folder in your current directory.

Once you’ve cloned the repository, you need to install the application’s dependencies. First, you should create a Python virtual environment. Go ahead and run the following commands:

Shell
$ cd reader/
$ python3 -m venv ./venv
$ source venv/bin/activate

These commands create and activate a new Python virtual environment in the reader/ directory, which is the root directory of the reader project.

Now you can install the dependencies of reader using pip:

Shell
(venv) $ python -m pip install feedparser html2text importlib_resources

Running the command above will install all the application’s dependencies in your active Python virtual environment.

Here’s an example of using reader to get a list of the latest articles, courses, podcast episodes, and other learning resources from Real Python:

Shell
(venv) $ python -m reader
The latest tutorials from Real Python (https://realpython.com/)
  0 The Django Template Language: Tags and Filters
  1 Pass by Reference in Python: Best Practices
  2 Using the "and" Boolean Operator in Python
    ...

This output will be different for you since reader lists the thirty latest learning resources in the feed. Each learning resource has an ID number. To get the contents of one item out of these learning resources, you can pass the corresponding ID number as a command-line argument to reader:

Shell
(venv) $ python -m reader 2
Using the "and" Boolean Operator in Python

Python has three Boolean operators, or **logical operators** : `and`, `or`,
and `not`. You can use them to check if certain conditions are met before
deciding the execution path your programs will follow. In this tutorial,
you'll learn about the `and` operator and how to use it in your code.
    ...

This command prints part of the contents of the article Using the “and” Boolean Operator in Python to your screen using the Markdown text format. You can read any of the available pieces of content by changing the ID number.

To create a Zip application from the reader repository, you’ll mainly use the reader/ folder. This folder has the following structure:

reader/
|
├── config.cfg
├── feed.py
├── __init__.py
├── __main__.py
└── viewer.py

The most significant fact to note from the reader/ directory is that it includes a __main__.py file. This file enables you to execute the package using the python -m reader command as you did before.

Having a __main__.py file provides the required entry-point script to create a Python Zip application. In this example, the __main__.py file is inside the reader package. If you create your Zip application using this directory structure, then your app won’t run because __main__.py won’t be able to import objects from reader.

To work around this, copy the reader package to an external directory called realpython/ and place the __main__.py file at its root. Then remove the __pycache__/ folder that results from running python -m reader, which you did before. You should end up with the following directory structure:

realpython/
├── reader/
│   ├── __init__.py
│   ├── config.cfg
│   ├── feed.py
│   └── viewer.py
│
└── __main__.py

With this new directory structure, you’re ready to create your first Python Zip application with zipapp. That’s what you’ll do in the following section.

Building a Python Zip Application With zipapp

To create your first Python Zip application, you’ll use zipapp. This module implements a user-friendly command-line interface that provides the required options for you to build a full-fledged Zip application with a single command. You can also use zipapp from your code through the module’s Python API, which mainly consists of a single function.

In the following two sections, you’ll learn about both approaches to building Zip applications using zipapp.

Using zipapp From the Command Line

The command-line interface of zipapp streamlines the process of packing Python applications into ZIP files. Internally, zipapp creates a Zip application from the source code by running the steps you learned before.

To run zipapp from the command line, you should use the following command syntax:

Shell
$ python -m zipapp <source> [OPTIONS]

If source is a directory, then this command creates a Zip application from that directory’s contents. If source is a file, then that file should be a ZIP file containing the application’s code. The contents of the input ZIP file are then copied to the target application archive.

Here’s a summary of the command-line options that zipapp accepts:

Options Description
-o <output_filename> or --output=<output_filename> Writes the Zip application into a file called output_filename. This option uses the output filename as you provide it. If you don’t provide this option, then zipapp uses the name of source with the .pyz extension.
-p <interpreter> or --python=<interpreter> Adds a shebang line to the application’s archive. If you’re on a POSIX system, then zipapp makes the application’s archive executable. If you don’t provide this option, then your app’s archive won’t have a shebang and won’t be executable.
-m <main_function> or --main=<main_function> Generates and writes a proper __main__.py file that executes main_function. The main_function argument should have the form "package.module:callable". You don’t need this option if you already have a __main__.py module.
-c or --compress Compresses the contents of source using the Deflate compression method. By default, zipapp just stores the contents of source without compressing it, which could make your application run faster.

This table provides a minimal description of the command-line options for zipapp. For further details on specific behaviors of each option, check out the official documentation.

Now that you know the basics of using zipapp from the command line, it’s time to build the reader Zip application. Go back to your terminal window and run the following command:

Shell
(venv) $ python -m zipapp realpython/ \
-o realpython.pyz \
-p "/usr/bin/env python3"

In this command, you set the realpython/ directory as the source for your Zip application. With the -o option, you provide a name for the application’s archive, realpython.pyz. Finally, the -p option lets you set the interpreter that zipapp will use to build the shebang line.

That’s it! Now you’ll have a realpython.pyz file in your current directory. You’ll learn how to execute that file in a moment.

To showcase the -m and --main command-line options of zipapp, say you decide to change the reader project layout and rename __main__.py to cli.py while moving the file back to the reader package. Go ahead and create a copy of your realpython/ directory and make the suggested changes. After that, the copy of realpython/ should look like this:

realpython_copy/
│
└── reader/
    ├── __init__.py
    ├── cli.py
    ├── config.cfg
    ├── feed.py
    └── viewer.py

At the moment, your application’s source directory doesn’t have a __main__.py module. The -m command-line option of zipapp allows you to generate it automatically:

Shell
$ python -m zipapp realpython_copy/ \
-o realpython.pyz \
-p "/usr/bin/env python3" \
-m "reader.cli:main"

This command takes the -m option with "reader.cli:main" as an argument. This input value tells zipapp that the entry-point callable for the Zip application is main() from the cli.py module in the reader package.

The resulting __main__.py file has the following contents:

Python
# -*- coding: utf-8 -*-
import reader.cli
reader.cli.main()

This __main__.py file is then packaged, along with your application’s source, into a ZIP archive named realpython.pyz.

Using zipapp From Python Code

Python’s zipapp also has an application programming interface (API) that you can use from your Python code. This API mostly consists of a function called create_archive(). With this function, you can create a Python Zip application quickly:

Python
>>> import zipapp

>>> zipapp.create_archive(
...     source="realpython/",
...     target="realpython.pyz",
...     interpreter="/usr/bin/env python3",
... )

This call to create_archive() takes a first argument called source that represents the source of your Zip application. The second argument, target, holds the filename for the app’s archive. Finally, interpreter holds the interpreter to build and add as the shebang line to the app’s ZIP archive.

Here’s a summary of the arguments that create_archive() can take:

  • source can take the following objects:
    • A string-based path to an existing source directory
    • A path-like object referring to an existing source directory
    • A string-based path to an existing Zip application archive
    • A path-like object referring to an existing Zip application archive
    • A file-like object opened for reading and pointing to an existing Zip application archive
  • target accepts the following objects:
    • A string-based path to the target Zip application file
    • A path-like object to the target Zip application file
  • interpreter specifies a Python interpreter, which is written as a shebang line at the beginning of the resulting application archive. Omitting this argument results in no shebang line and no execution permission for the application.
  • main specifies the name of the callable that zipapp will use as the entry point for the target archive. You provide a value for main when you don’t have a __main__.py file.
  • filter takes a Boolean-valued function that should return True if a given file in the source directory should be added to the final Zip application file.
  • compressed accepts a Boolean value that determines whether you want to compress the source files or not.

Most of these arguments have an equivalent option in the command-line interface of zipapp. The example above uses just the first three arguments. Depending on your specific needs, you might use other arguments as well.

Running a Python Zip Application

So far, you’ve learned how to create Python Zip applications using zipapp from the command line and Python code. Now it’s time to run your realpython.pyz app to make sure it works.

If you’re on a Unix-like system, then you can run your application by executing the following:

Shell
(venv) $ ./realpython.pyz
The latest tutorials from Real Python (https://realpython.com/)
  0 The Django Template Language: Tags and Filters
  1 Pass by Reference in Python: Best Practices
  2 Using the "and" Boolean Operator in Python
    ...

Cool! It works! Now you have a single application file that you can quickly share with friends and colleagues.

You don’t need to invoke Python to run the application from the command line anymore. Since your Zip application archive has a shebang line at the beginning, the operating system will automatically use your active Python interpreter to run the contents of the target archive.

If you’re on Windows, then your Python installation should have registered .pyz and .pyzw files and should be able to run them:

Windows Command Prompt
C:\> .\realpython.pyz
The latest tutorials from Real Python (https://realpython.com/)
  0 The Django Template Language: Tags and Filters
  1 Pass by Reference in Python: Best Practices
  2 Using the "and" Boolean Operator in Python
    ...

The reader application you’re using in this tutorial has a command-line interface, so it makes sense to run it from the command line or terminal window. However, if you have a GUI application, then you’ll be able to run it from your favorite file manager as you usually run executable apps.

Again, you can execute any Zip application by invoking the appropriate Python interpreter with the application’s filename as an argument:

Shell
$ python3 realpython.pyz
The latest tutorials from Real Python (https://realpython.com/)
  0 The Django Template Language: Tags and Filters
  1 Pass by Reference in Python: Best Practices
  2 Using the "and" Boolean Operator in Python
    ...

In this example, you use the system Python 3.x installation to run realpython.pyz. If you have many Python versions on your system, then you may need to be more specific and use a command like python3.9 realpython.pyz.

Note that whatever interpreter you use, you need to have the application’s dependencies installed. Otherwise, your application will fail. Having unsatisfied dependencies is a common issue with Python Zip applications. To work around this annoying situation, you can create a standalone application, which is the topic of the following section.

Creating a Standalone Python Zip App With zipapp

You can also use zipapp to create self-contained or standalone Python Zip applications. This type of application bundles all its dependencies into the app’s ZIP file. This way, your end users only need a suitable Python interpreter for running the application. They don’t need to worry about dependencies.

To create a standalone Python Zip application, you first need to install its dependencies into the source directory using pip. Go ahead and create a copy of your realpython/ directory with the name realpython_sa/. Then run the following command to install the app’s dependencies:

Shell
(venv) $ python -m pip install feedparser html2text importlib_resources \
--target realpython_sa/

This command installs all the dependencies of reader using pip install with the --target option. The documentation of pip says that this option allows you to install packages into a target directory. In this example, that directory must be your app’s source directory, realpython_sa/.

Once you’ve installed the dependencies of reader into realpython_sa/, you can optionally remove the *.dist-info directories that pip creates. These directories contain several files with metadata that pip uses to manage the corresponding package. Since you don’t need that information any longer, you can get rid of it.

The final step in the process is to build the Zip application using zipapp as usual:

Shell
(venv) $ python -m zipapp realpython_sa/ \
-p "/usr/bin/env python3" \
-o realpython_sa.pyz \
-c

This command produces a standalone Python Zip application in realpython_sa.pyz. To run this application, your end users just need to have a proper Python 3 interpreter on their machine. The advantage of this kind of application compared to a regular Zip application is that your end users don’t need to install any dependencies to run the application. Go ahead and give it a try!

In the example above, you use the -c option of zipapp to compress the contents of realpython_sa/. This option can be fairly convenient for applications with many dependencies that take a significant amount of disk space.

Creating a Python Zip Application Manually

As you’ve already learned, zipapp has been available in the standard library since Python 3.5. If you’re using a Python version lower than that, then you can still build your Python Zip applications manually without the need for zipapp.

In the following two sections, you’ll learn how to create a Zip application using zipfile from the Python standard library. You’ll also learn how to use some command-line tools to achieve the same task.

Using Python’s zipfile

You already have the realpython/ directory with the reader application’s source files. The next step to manually build a Python Zip application from that directory is to archive it into a ZIP file. To do that, you can use zipfile. This module provides convenient tools to create, read, write, append, and list the contents of ZIP files.

The code below shows how to create the reader Zip application using zipfile.ZipFile and a few other tools. For example, the code relies on pathlib and stat to read the contents of the source directory and set execution permission to the resulting file:

Python
# build_app.py

import pathlib
import stat
import zipfile

app_source = pathlib.Path("realpython/")
app_filename = pathlib.Path("realpython.pyz")

with open(app_filename, "wb") as app_file:
    # 1. Prepend a shebang line
    shebang_line = b"#!/usr/bin/env python3\n"
    app_file.write(shebang_line)

    # 2. Zip the app's source
    with zipfile.ZipFile(app_file, "w") as zip_app:
        for file in app_source.rglob("*"):
            member_file = file.relative_to(app_source)
            zip_app.write(file, member_file)

# 3. Make the app executable (POSIX systems only)
current_mode = app_filename.stat().st_mode
exec_mode = stat.S_IEXEC
app_filename.chmod(current_mode | exec_mode)

This code runs the three required steps to end up with a full-fledged Python Zip application. The first step adds a shebang line to the application’s file. It uses open() in a with statement to create a file object (app_file) to handle the application. Then it calls .write() to write the shebang line at the beginning of app_file.

The second step zips the application’s source directory contents using ZipFile in a nested with statement. The for loop iterates over the files in realpython/ using pathlib.Path.rglob() and writes them to zip_app. Note that .rglob() searches for files and directories recursively through the target folder, app_source.

The filename, member_file, of each file in the final ZIP archive needs to be relative to the app’s source directory to ensure that the internal structure of the application’s ZIP file matches the structure of the source, realpython/. That’s why you use pathlib.Path.relative_to() in the example above.

Finally, the third step makes the application’s file executable using pathlib.Path.chmod(). To do this, you first get the current mode of the file using pathlib.Path.stat() and then combine this mode with stat.S_IEXEC using the bitwise OR operator (|). Note that this step only has an effect on POSIX systems.

After running these steps, your realpython.pyz application is ready to go. Go ahead and give it a try from your command line.

Using Unix Command-Line Tools

If you’re on a Unix-like system, such as Linux and macOS, then you can also run the three steps from the previous section using specific tools from your command line. For example, you can use the zip command to zip the contents of the application’s source directory:

Shell
$ cd realpython/
$ zip -r ../realpython.zip *

In this example, you first cd into the realpython/ directory. Then you zip the contents of realpython/ into realpython.zip using the zip command with the -r option. This option recursively traverses the target directory.

The next step is to add a shebang line to the ZIP file, realpython.zip, and save it as realpython.pyz. To that end, you can use the echo and cat commands in a pipe:

Shell
$ cd ..
$ echo '#!/usr/bin/env python3' | cat - realpython.zip > realpython.pyz

The cd .. command gets you back out of realpython/. The echo command sends '#!/usr/bin/env python3' to the standard output. The pipe character (|) passes the contents of the standard output to the cat command. Then cat concatenates the standard output (-) with the contents of realpython.zip. Finally, the greater-than sign (>) redirects the cat output to the realpython.pyz file.

Finally, you may want to make the application’s file executable with the chmod command:

Shell
$ chmod +x realpython.pyz

Here, chmod adds execution permission (+x) to realpython.pyz. Now you’re ready to run your application again, which you can do from the command line as usual.

Using Third-Party Tools to Create Python Apps

In the Python ecosystem, you’ll find a few third-party libraries that work similarly to zipapp. They provide many more features and can be useful to explore. In this section, you’ll learn about two of these third-party libraries: pex and shiv.

The pex project provides a tool to create PEX files. PEX stands for Python executable and is a file format that stores self-contained executable Python virtual environments. The pex tool packs these environments into ZIP files with a shebang line and a __main__.py module, which allows you to execute the resulting PEX file directly. The pex tool is an expansion on the ideas outlined in PEP 441.

To create an executable application with pex, you first need to install it:

Shell
(venv) $ python -m pip install pex
(venv) $ pex --help
pex [-o OUTPUT.PEX] [options] [-- arg1 arg2 ...]

pex builds a PEX (Python Executable) file based on the given specifications:
sources, requirements, their dependencies and other options.
Command-line options can be provided in one or more files by prefixing the
filenames with an @ symbol. These files must contain one argument per line.
    ...

The pex tool provides a rich set of options that allows you to fine-tune your PEX files. The following command shows how to create a PEX file for the reader project:

Shell
(venv) $ pex realpython-reader -c realpython -o realpython.pex

This command creates realpython.pex in your current directory. This file is a Python executable for reader. Note that pex handles the installations of reader and all its dependencies from PyPI. The reader project is available on PyPI with the name realpython-reader, which is why you use that name as the first argument to pex.

The -c option allows you to define which console script the application will use. In this case, the console script is realpython as defined in the setup.py file of reader. The -o option specifies the output file. As usual, you can execute ./realpython.pex from your command line to run the application.

Since the contents of the .pex file are unzipped before execution, PEX applications solve the limitation of zipapp applications and allow you to execute code from .pyd, .so, and .dll files.

A final detail to note is that pex creates and packs a Python virtual environment in the resulting PEX file. This behavior makes your Zip application a lot bigger than a regular app created with zipapp.

The second tool you’ll learn about in this section is shiv. It’s a command-line utility for building self-contained Python Zip applications as described in PEP 441. The advantage of shiv compared to zipapp is that shiv automatically includes all of the app’s dependencies in the final archive and makes them available in Python’s module search path.

To use shiv, you need to install it from PyPI:

Shell
(venv) $ python -m pip install shiv
(venv) $ shiv --help
Usage: shiv [OPTIONS] [PIP_ARGS]...

  Shiv is a command line utility for building fully self-contained Python
  zipapps as outlined in PEP 441, but with all their dependencies included!
    ...

The --help option shows a complete usage message that you can check for a quick understanding of how shiv works.

To build a Python Zip application with shiv, you need an installable Python application with a setup.py or pyproject.toml file. Fortunately, the original reader project from GitHub fulfills this requirement. Go back to the directory containing the cloned reader/ folder and run the following command:

Shell
(venv) $ shiv -c realpython \
-o realpython.pyz reader/ \
-p "/usr/bin/env python3"

Like the pex tool, shiv has a -c option to define a console script for the application. The -o and -p options allow you to provide an output filename and a proper Python interpreter, respectively.

Unlike zipapp, shiv enables you to use the .pyd, .so, and .dll files you store in the application’s archive. To do so, shiv includes a special bootstrap function within the archive. This function unpacks the application’s dependencies into a .shiv/ directory in your home folder and adds them to Python’s sys.path.

This feature allows you to create standalone applications that include libraries that are partially written in C and C++ for speed and efficiency, such as NumPy.

Conclusion

Having a quick and efficient way to distribute your Python executable applications can make the difference in satisfying your end users’ needs. Python Zip applications provide an effective and accessible solution for you to bundle and distribute ready-to-run applications. You can use zipapp from the Python standard library to quickly create your own executable Zip applications and pass them along to your end users.

In this tutorial, you learned:

  • What a Python Zip application is
  • How Zip applications work internally
  • How to build your own Python Zip applications with zipapp
  • What standalone Zip apps are and how to create them using pip and zipapp
  • How to create Python Zip applications manually using command-line tools

With this knowledge, you’re ready to quickly create Python Zip applications as a convenient way to distribute your Python programs and scripts to your end users.

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Leodanis Pozo Ramos

Leodanis is an industrial engineer who loves Python and software development. He's a self-taught Python developer with 6+ years of experience. He's an avid technical writer with a growing number of articles published on Real Python and other sites.

» More about Leodanis

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Master Real-World Python Skills With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python Skills
With Unlimited Access to Real Python

Locked learning resources

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal.


Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!