1:mod:`!zipapp` --- Manage executable Python zip archives 2======================================================== 3 4.. module:: zipapp 5 :synopsis: Manage executable Python zip archives 6 7.. versionadded:: 3.5 8 9**Source code:** :source:`Lib/zipapp.py` 10 11.. index:: 12 single: Executable Zip Files 13 14-------------- 15 16This module provides tools to manage the creation of zip files containing 17Python code, which can be :ref:`executed directly by the Python interpreter 18<using-on-interface-options>`. The module provides both a 19:ref:`zipapp-command-line-interface` and a :ref:`zipapp-python-api`. 20 21 22Basic Example 23------------- 24 25The following example shows how the :ref:`zipapp-command-line-interface` 26can be used to create an executable archive from a directory containing 27Python code. When run, the archive will execute the ``main`` function from 28the module ``myapp`` in the archive. 29 30.. code-block:: shell-session 31 32 $ python -m zipapp myapp -m "myapp:main" 33 $ python myapp.pyz 34 <output from myapp> 35 36 37.. _zipapp-command-line-interface: 38 39Command-Line Interface 40---------------------- 41 42When called as a program from the command line, the following form is used: 43 44.. code-block:: shell-session 45 46 $ python -m zipapp source [options] 47 48If *source* is a directory, this will create an archive from the contents of 49*source*. If *source* is a file, it should be an archive, and it will be 50copied to the target archive (or the contents of its shebang line will be 51displayed if the --info option is specified). 52 53The following options are understood: 54 55.. program:: zipapp 56 57.. option:: -o <output>, --output=<output> 58 59 Write the output to a file named *output*. If this option is not specified, 60 the output filename will be the same as the input *source*, with the 61 extension ``.pyz`` added. If an explicit filename is given, it is used as 62 is (so a ``.pyz`` extension should be included if required). 63 64 An output filename must be specified if the *source* is an archive (and in 65 that case, *output* must not be the same as *source*). 66 67.. option:: -p <interpreter>, --python=<interpreter> 68 69 Add a ``#!`` line to the archive specifying *interpreter* as the command 70 to run. Also, on POSIX, make the archive executable. The default is to 71 write no ``#!`` line, and not make the file executable. 72 73.. option:: -m <mainfn>, --main=<mainfn> 74 75 Write a ``__main__.py`` file to the archive that executes *mainfn*. The 76 *mainfn* argument should have the form "pkg.mod:fn", where "pkg.mod" is a 77 package/module in the archive, and "fn" is a callable in the given module. 78 The ``__main__.py`` file will execute that callable. 79 80 :option:`--main` cannot be specified when copying an archive. 81 82.. option:: -c, --compress 83 84 Compress files with the deflate method, reducing the size of the output 85 file. By default, files are stored uncompressed in the archive. 86 87 :option:`--compress` has no effect when copying an archive. 88 89 .. versionadded:: 3.7 90 91.. option:: --info 92 93 Display the interpreter embedded in the archive, for diagnostic purposes. In 94 this case, any other options are ignored and SOURCE must be an archive, not a 95 directory. 96 97.. option:: -h, --help 98 99 Print a short usage message and exit. 100 101 102.. _zipapp-python-api: 103 104Python API 105---------- 106 107The module defines two convenience functions: 108 109 110.. function:: create_archive(source, target=None, interpreter=None, main=None, filter=None, compressed=False) 111 112 Create an application archive from *source*. The source can be any 113 of the following: 114 115 * The name of a directory, or a :term:`path-like object` referring 116 to a directory, in which case a new application archive will be 117 created from the content of that directory. 118 * The name of an existing application archive file, or a :term:`path-like object` 119 referring to such a file, in which case the file is copied to 120 the target (modifying it to reflect the value given for the *interpreter* 121 argument). The file name should include the ``.pyz`` extension, if required. 122 * A file object open for reading in bytes mode. The content of the 123 file should be an application archive, and the file object is 124 assumed to be positioned at the start of the archive. 125 126 The *target* argument determines where the resulting archive will be 127 written: 128 129 * If it is the name of a file, or a :term:`path-like object`, 130 the archive will be written to that file. 131 * If it is an open file object, the archive will be written to that 132 file object, which must be open for writing in bytes mode. 133 * If the target is omitted (or ``None``), the source must be a directory 134 and the target will be a file with the same name as the source, with 135 a ``.pyz`` extension added. 136 137 The *interpreter* argument specifies the name of the Python 138 interpreter with which the archive will be executed. It is written as 139 a "shebang" line at the start of the archive. On POSIX, this will be 140 interpreted by the OS, and on Windows it will be handled by the Python 141 launcher. Omitting the *interpreter* results in no shebang line being 142 written. If an interpreter is specified, and the target is a 143 filename, the executable bit of the target file will be set. 144 145 The *main* argument specifies the name of a callable which will be 146 used as the main program for the archive. It can only be specified if 147 the source is a directory, and the source does not already contain a 148 ``__main__.py`` file. The *main* argument should take the form 149 "pkg.module:callable" and the archive will be run by importing 150 "pkg.module" and executing the given callable with no arguments. It 151 is an error to omit *main* if the source is a directory and does not 152 contain a ``__main__.py`` file, as otherwise the resulting archive 153 would not be executable. 154 155 The optional *filter* argument specifies a callback function that 156 is passed a Path object representing the path to the file being added 157 (relative to the source directory). It should return ``True`` if the 158 file is to be added. 159 160 The optional *compressed* argument determines whether files are 161 compressed. If set to ``True``, files in the archive are compressed 162 with the deflate method; otherwise, files are stored uncompressed. 163 This argument has no effect when copying an existing archive. 164 165 If a file object is specified for *source* or *target*, it is the 166 caller's responsibility to close it after calling create_archive. 167 168 When copying an existing archive, file objects supplied only need 169 ``read`` and ``readline``, or ``write`` methods. When creating an 170 archive from a directory, if the target is a file object it will be 171 passed to the ``zipfile.ZipFile`` class, and must supply the methods 172 needed by that class. 173 174 .. versionchanged:: 3.7 175 Added the *filter* and *compressed* parameters. 176 177.. function:: get_interpreter(archive) 178 179 Return the interpreter specified in the ``#!`` line at the start of the 180 archive. If there is no ``#!`` line, return :const:`None`. 181 The *archive* argument can be a filename or a file-like object open 182 for reading in bytes mode. It is assumed to be at the start of the archive. 183 184 185.. _zipapp-examples: 186 187Examples 188-------- 189 190Pack up a directory into an archive, and run it. 191 192.. code-block:: shell-session 193 194 $ python -m zipapp myapp 195 $ python myapp.pyz 196 <output from myapp> 197 198The same can be done using the :func:`create_archive` function:: 199 200 >>> import zipapp 201 >>> zipapp.create_archive('myapp', 'myapp.pyz') 202 203To make the application directly executable on POSIX, specify an interpreter 204to use. 205 206.. code-block:: shell-session 207 208 $ python -m zipapp myapp -p "/usr/bin/env python" 209 $ ./myapp.pyz 210 <output from myapp> 211 212To replace the shebang line on an existing archive, create a modified archive 213using the :func:`create_archive` function:: 214 215 >>> import zipapp 216 >>> zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3') 217 218To update the file in place, do the replacement in memory using a :class:`~io.BytesIO` 219object, and then overwrite the source afterwards. Note that there is a risk 220when overwriting a file in place that an error will result in the loss of 221the original file. This code does not protect against such errors, but 222production code should do so. Also, this method will only work if the archive 223fits in memory:: 224 225 >>> import zipapp 226 >>> import io 227 >>> temp = io.BytesIO() 228 >>> zipapp.create_archive('myapp.pyz', temp, '/usr/bin/python2') 229 >>> with open('myapp.pyz', 'wb') as f: 230 >>> f.write(temp.getvalue()) 231 232 233.. _zipapp-specifying-the-interpreter: 234 235Specifying the Interpreter 236-------------------------- 237 238Note that if you specify an interpreter and then distribute your application 239archive, you need to ensure that the interpreter used is portable. The Python 240launcher for Windows supports most common forms of POSIX ``#!`` line, but there 241are other issues to consider: 242 243* If you use "/usr/bin/env python" (or other forms of the "python" command, 244 such as "/usr/bin/python"), you need to consider that your users may have 245 either Python 2 or Python 3 as their default, and write your code to work 246 under both versions. 247* If you use an explicit version, for example "/usr/bin/env python3" your 248 application will not work for users who do not have that version. (This 249 may be what you want if you have not made your code Python 2 compatible). 250* There is no way to say "python X.Y or later", so be careful of using an 251 exact version like "/usr/bin/env python3.4" as you will need to change your 252 shebang line for users of Python 3.5, for example. 253 254Typically, you should use an "/usr/bin/env python2" or "/usr/bin/env python3", 255depending on whether your code is written for Python 2 or 3. 256 257 258Creating Standalone Applications with zipapp 259-------------------------------------------- 260 261Using the :mod:`zipapp` module, it is possible to create self-contained Python 262programs, which can be distributed to end users who only need to have a 263suitable version of Python installed on their system. The key to doing this 264is to bundle all of the application's dependencies into the archive, along 265with the application code. 266 267The steps to create a standalone archive are as follows: 268 2691. Create your application in a directory as normal, so you have a ``myapp`` 270 directory containing a ``__main__.py`` file, and any supporting application 271 code. 272 2732. Install all of your application's dependencies into the ``myapp`` directory, 274 using pip: 275 276 .. code-block:: shell-session 277 278 $ python -m pip install -r requirements.txt --target myapp 279 280 (this assumes you have your project requirements in a ``requirements.txt`` 281 file - if not, you can just list the dependencies manually on the pip command 282 line). 283 2843. Package the application using: 285 286 .. code-block:: shell-session 287 288 $ python -m zipapp -p "interpreter" myapp 289 290This will produce a standalone executable, which can be run on any machine with 291the appropriate interpreter available. See :ref:`zipapp-specifying-the-interpreter` 292for details. It can be shipped to users as a single file. 293 294On Unix, the ``myapp.pyz`` file is executable as it stands. You can rename the 295file to remove the ``.pyz`` extension if you prefer a "plain" command name. On 296Windows, the ``myapp.pyz[w]`` file is executable by virtue of the fact that 297the Python interpreter registers the ``.pyz`` and ``.pyzw`` file extensions 298when installed. 299 300 301Caveats 302~~~~~~~ 303 304If your application depends on a package that includes a C extension, that 305package cannot be run from a zip file (this is an OS limitation, as executable 306code must be present in the filesystem for the OS loader to load it). In this 307case, you can exclude that dependency from the zipfile, and either require 308your users to have it installed, or ship it alongside your zipfile and add code 309to your ``__main__.py`` to include the directory containing the unzipped 310module in ``sys.path``. In this case, you will need to make sure to ship 311appropriate binaries for your target architecture(s) (and potentially pick the 312correct version to add to ``sys.path`` at runtime, based on the user's machine). 313 314 315The Python Zip Application Archive Format 316----------------------------------------- 317 318Python has been able to execute zip files which contain a ``__main__.py`` file 319since version 2.6. In order to be executed by Python, an application archive 320simply has to be a standard zip file containing a ``__main__.py`` file which 321will be run as the entry point for the application. As usual for any Python 322script, the parent of the script (in this case the zip file) will be placed on 323:data:`sys.path` and thus further modules can be imported from the zip file. 324 325The zip file format allows arbitrary data to be prepended to a zip file. The 326zip application format uses this ability to prepend a standard POSIX "shebang" 327line to the file (``#!/path/to/interpreter``). 328 329Formally, the Python zip application format is therefore: 330 3311. An optional shebang line, containing the characters ``b'#!'`` followed by an 332 interpreter name, and then a newline (``b'\n'``) character. The interpreter 333 name can be anything acceptable to the OS "shebang" processing, or the Python 334 launcher on Windows. The interpreter should be encoded in UTF-8 on Windows, 335 and in :func:`sys.getfilesystemencoding` on POSIX. 3362. Standard zipfile data, as generated by the :mod:`zipfile` module. The 337 zipfile content *must* include a file called ``__main__.py`` (which must be 338 in the "root" of the zipfile - i.e., it cannot be in a subdirectory). The 339 zipfile data can be compressed or uncompressed. 340 341If an application archive has a shebang line, it may have the executable bit set 342on POSIX systems, to allow it to be executed directly. 343 344There is no requirement that the tools in this module are used to create 345application archives - the module is a convenience, but archives in the above 346format created by any means are acceptable to Python. 347 348