blob: 728315251e082439bcd896069d9029d25cd53205 [file] [log] [blame]
Andrés Delfino271818f2018-09-14 14:13:09 -03001:mod:`zipapp` --- Manage executable Python zip archives
Brett Cannoncc4dfc12015-03-13 10:40:49 -04002=======================================================
3
4.. module:: zipapp
Andrés Delfino271818f2018-09-14 14:13:09 -03005 :synopsis: Manage executable Python zip archives
Brett Cannoncc4dfc12015-03-13 10:40:49 -04006
Brett Cannoncc4dfc12015-03-13 10:40:49 -04007.. versionadded:: 3.5
8
9**Source code:** :source:`Lib/zipapp.py`
10
Terry Jan Reedyfa089b92016-06-11 15:02:54 -040011.. index::
12 single: Executable Zip Files
13
Brett Cannoncc4dfc12015-03-13 10:40:49 -040014--------------
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
Martin Panter00ccacc2016-04-16 04:59:38 +000025The following example shows how the :ref:`zipapp-command-line-interface`
Brett Cannoncc4dfc12015-03-13 10:40:49 -040026can 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
Serhiy Storchaka46936d52018-04-08 19:18:04 +030030.. code-block:: shell-session
Brett Cannoncc4dfc12015-03-13 10:40:49 -040031
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
Serhiy Storchaka46936d52018-04-08 19:18:04 +030044.. code-block:: shell-session
Brett Cannoncc4dfc12015-03-13 10:40:49 -040045
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.. cmdoption:: -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.. cmdoption:: -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.. cmdoption:: -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
Zhiming Wangd87b1052017-09-29 13:31:52 -040082.. cmdoption:: -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
Berker Peksag12d60562017-11-04 15:17:56 +030089 .. versionadded:: 3.7
90
Brett Cannoncc4dfc12015-03-13 10:40:49 -040091.. cmdoption:: --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.. cmdoption:: -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
Zhiming Wangd87b1052017-09-29 13:31:52 -0400110.. function:: create_archive(source, target=None, interpreter=None, main=None, filter=None, compressed=False)
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400111
112 Create an application archive from *source*. The source can be any
113 of the following:
Brett Cannon64e4f7f2015-03-13 10:42:08 -0400114
Serhiy Storchaka4aec9a82017-03-25 13:05:23 +0200115 * The name of a directory, or a :term:`path-like object` referring
Paul Moorea4d4dd32015-03-22 15:32:36 +0000116 to a directory, in which case a new application archive will be
117 created from the content of that directory.
Serhiy Storchaka4aec9a82017-03-25 13:05:23 +0200118 * 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
Paul Moorea4d4dd32015-03-22 15:32:36 +0000120 the target (modifying it to reflect the value given for the *interpreter*
121 argument). The file name should include the ``.pyz`` extension, if required.
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400122 * 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.
Brett Cannon64e4f7f2015-03-13 10:42:08 -0400125
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400126 The *target* argument determines where the resulting archive will be
127 written:
Brett Cannon64e4f7f2015-03-13 10:42:08 -0400128
Serhiy Storchaka4aec9a82017-03-25 13:05:23 +0200129 * If it is the name of a file, or a :term:`path-like object`,
Paul Moorea4d4dd32015-03-22 15:32:36 +0000130 the archive will be written to that file.
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400131 * 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.
Serhiy Storchakaecf41da2016-10-19 16:29:26 +0300133 * If the target is omitted (or ``None``), the source must be a directory
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400134 and the target will be a file with the same name as the source, with
135 a ``.pyz`` extension added.
Brett Cannon64e4f7f2015-03-13 10:42:08 -0400136
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400137 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.
Brett Cannon64e4f7f2015-03-13 10:42:08 -0400144
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400145 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.
Brett Cannon64e4f7f2015-03-13 10:42:08 -0400154
Paul Moore0780bf72017-08-26 18:04:12 +0100155 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.
Jeffrey Rackauckasb811d662017-08-09 06:37:17 -0700159
Zhiming Wangd87b1052017-09-29 13:31:52 -0400160 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
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400165 If a file object is specified for *source* or *target*, it is the
166 caller's responsibility to close it after calling create_archive.
Brett Cannon64e4f7f2015-03-13 10:42:08 -0400167
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400168 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
Paul Moore0780bf72017-08-26 18:04:12 +0100174 .. versionadded:: 3.7
Zhiming Wangd87b1052017-09-29 13:31:52 -0400175 Added the *filter* and *compressed* arguments.
Paul Moore0780bf72017-08-26 18:04:12 +0100176
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400177.. 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
Serhiy Storchaka46936d52018-04-08 19:18:04 +0300192.. code-block:: shell-session
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400193
194 $ python -m zipapp myapp
195 $ python myapp.pyz
196 <output from myapp>
197
Stéphane Wirtel07fbbfd2018-10-05 16:17:18 +0200198The same can be done using the :func:`create_archive` function::
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400199
200 >>> import zipapp
201 >>> zipapp.create_archive('myapp.pyz', 'myapp')
202
203To make the application directly executable on POSIX, specify an interpreter
204to use.
205
Serhiy Storchaka46936d52018-04-08 19:18:04 +0300206.. code-block:: shell-session
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400207
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:`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
Cheryl Sabella4be79f22018-03-20 18:23:19 -0400232
233.. _zipapp-specifying-the-interpreter:
234
235Specifying the Interpreter
236--------------------------
237
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400238Note 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
Cheryl Sabella4be79f22018-03-20 18:23:19 -0400254Typically, 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
Serhiy Storchaka46936d52018-04-08 19:18:04 +0300276 .. code-block:: shell-session
Cheryl Sabella4be79f22018-03-20 18:23:19 -0400277
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. Optionally, delete the ``.dist-info`` directories created by pip in the
285 ``myapp`` directory. These hold metadata for pip to manage the packages, and
286 as you won't be making any further use of pip they aren't required -
287 although it won't do any harm if you leave them.
288
2894. Package the application using:
290
Serhiy Storchaka46936d52018-04-08 19:18:04 +0300291 .. code-block:: shell-session
Cheryl Sabella4be79f22018-03-20 18:23:19 -0400292
293 $ python -m zipapp -p "interpreter" myapp
294
295This will produce a standalone executable, which can be run on any machine with
296the appropriate interpreter available. See :ref:`zipapp-specifying-the-interpreter`
297for details. It can be shipped to users as a single file.
298
299On Unix, the ``myapp.pyz`` file is executable as it stands. You can rename the
300file to remove the ``.pyz`` extension if you prefer a "plain" command name. On
301Windows, the ``myapp.pyz[w]`` file is executable by virtue of the fact that
302the Python interpreter registers the ``.pyz`` and ``.pyzw`` file extensions
303when installed.
304
305
306Making a Windows executable
307~~~~~~~~~~~~~~~~~~~~~~~~~~~
308
309On Windows, registration of the ``.pyz`` extension is optional, and
310furthermore, there are certain places that don't recognise registered
311extensions "transparently" (the simplest example is that
312``subprocess.run(['myapp'])`` won't find your application - you need to
313explicitly specify the extension).
314
315On Windows, therefore, it is often preferable to create an executable from the
316zipapp. This is relatively easy, although it does require a C compiler. The
317basic approach relies on the fact that zipfiles can have arbitrary data
318prepended, and Windows exe files can have arbitrary data appended. So by
319creating a suitable launcher and tacking the ``.pyz`` file onto the end of it,
320you end up with a single-file executable that runs your application.
321
322A suitable launcher can be as simple as the following::
323
324 #define Py_LIMITED_API 1
325 #include "Python.h"
326
327 #define WIN32_LEAN_AND_MEAN
328 #include <windows.h>
329
330 #ifdef WINDOWS
331 int WINAPI wWinMain(
332 HINSTANCE hInstance, /* handle to current instance */
333 HINSTANCE hPrevInstance, /* handle to previous instance */
334 LPWSTR lpCmdLine, /* pointer to command line */
335 int nCmdShow /* show state of window */
336 )
337 #else
338 int wmain()
339 #endif
340 {
341 wchar_t **myargv = _alloca((__argc + 1) * sizeof(wchar_t*));
342 myargv[0] = __wargv[0];
343 memcpy(myargv + 1, __wargv, __argc * sizeof(wchar_t *));
344 return Py_Main(__argc+1, myargv);
345 }
346
347If you define the ``WINDOWS`` preprocessor symbol, this will generate a
348GUI executable, and without it, a console executable.
349
350To compile the executable, you can either just use the standard MSVC
351command line tools, or you can take advantage of the fact that distutils
352knows how to compile Python source::
353
354 >>> from distutils.ccompiler import new_compiler
355 >>> import distutils.sysconfig
356 >>> import sys
357 >>> import os
358 >>> from pathlib import Path
359
360 >>> def compile(src):
361 >>> src = Path(src)
362 >>> cc = new_compiler()
363 >>> exe = src.stem
364 >>> cc.add_include_dir(distutils.sysconfig.get_python_inc())
365 >>> cc.add_library_dir(os.path.join(sys.base_exec_prefix, 'libs'))
366 >>> # First the CLI executable
367 >>> objs = cc.compile([str(src)])
368 >>> cc.link_executable(objs, exe)
369 >>> # Now the GUI executable
370 >>> cc.define_macro('WINDOWS')
371 >>> objs = cc.compile([str(src)])
372 >>> cc.link_executable(objs, exe + 'w')
373
374 >>> if __name__ == "__main__":
375 >>> compile("zastub.c")
376
377The resulting launcher uses the "Limited ABI", so it will run unchanged with
378any version of Python 3.x. All it needs is for Python (``python3.dll``) to be
379on the user's ``PATH``.
380
381For a fully standalone distribution, you can distribute the launcher with your
382application appended, bundled with the Python "embedded" distribution. This
383will run on any PC with the appropriate architecture (32 bit or 64 bit).
384
385
386Caveats
387~~~~~~~
388
389There are some limitations to the process of bundling your application into
390a single file. In most, if not all, cases they can be addressed without
391needing major changes to your application.
392
3931. If your application depends on a package that includes a C extension, that
394 package cannot be run from a zip file (this is an OS limitation, as executable
395 code must be present in the filesystem for the OS loader to load it). In this
396 case, you can exclude that dependency from the zipfile, and either require
397 your users to have it installed, or ship it alongside your zipfile and add code
398 to your ``__main__.py`` to include the directory containing the unzipped
399 module in ``sys.path``. In this case, you will need to make sure to ship
400 appropriate binaries for your target architecture(s) (and potentially pick the
401 correct version to add to ``sys.path`` at runtime, based on the user's machine).
402
4032. If you are shipping a Windows executable as described above, you either need to
404 ensure that your users have ``python3.dll`` on their PATH (which is not the
405 default behaviour of the installer) or you should bundle your application with
406 the embedded distribution.
407
4083. The suggested launcher above uses the Python embedding API. This means that in
409 your application, ``sys.executable`` will be your application, and *not* a
410 conventional Python interpreter. Your code and its dependencies need to be
411 prepared for this possibility. For example, if your application uses the
412 :mod:`multiprocessing` module, it will need to call
413 :func:`multiprocessing.set_executable` to let the module know where to find the
414 standard Python interpreter.
415
416
Brett Cannoncc4dfc12015-03-13 10:40:49 -0400417The Python Zip Application Archive Format
418-----------------------------------------
419
420Python has been able to execute zip files which contain a ``__main__.py`` file
421since version 2.6. In order to be executed by Python, an application archive
422simply has to be a standard zip file containing a ``__main__.py`` file which
423will be run as the entry point for the application. As usual for any Python
424script, the parent of the script (in this case the zip file) will be placed on
425:data:`sys.path` and thus further modules can be imported from the zip file.
426
427The zip file format allows arbitrary data to be prepended to a zip file. The
428zip application format uses this ability to prepend a standard POSIX "shebang"
429line to the file (``#!/path/to/interpreter``).
430
431Formally, the Python zip application format is therefore:
432
4331. An optional shebang line, containing the characters ``b'#!'`` followed by an
434 interpreter name, and then a newline (``b'\n'``) character. The interpreter
435 name can be anything acceptable to the OS "shebang" processing, or the Python
436 launcher on Windows. The interpreter should be encoded in UTF-8 on Windows,
437 and in :func:`sys.getfilesystemencoding()` on POSIX.
4382. Standard zipfile data, as generated by the :mod:`zipfile` module. The
439 zipfile content *must* include a file called ``__main__.py`` (which must be
440 in the "root" of the zipfile - i.e., it cannot be in a subdirectory). The
441 zipfile data can be compressed or uncompressed.
442
443If an application archive has a shebang line, it may have the executable bit set
444on POSIX systems, to allow it to be executed directly.
445
446There is no requirement that the tools in this module are used to create
447application archives - the module is a convenience, but archives in the above
448format created by any means are acceptable to Python.
Brett Cannon64e4f7f2015-03-13 10:42:08 -0400449