pip install zipapps -U
- zipapps with requirements
-
python3 -m zipapps -u AUTO -a entry.py -m entry:main -o app.pyz aiohttp,psutils
-
- run app.pyz
-
python3 app.pyz
- cache will be unzipped to
./zipapps_cache/app
-
- zipapps with requirements
-
python3 -m zipapps -u AUTO -o venv.pyz -r requirements.txt
-
- run entry.py with venv.pyz
-
python3 app.pyz entry.py
- cache will be unzipped to
./zipapps_cache/venv
-
- Package with
zipappspython3 -m zipapps -c -m zipapps.__main__:main -o zipapps.pyz -p /usr/bin/python3 zipapps
- Check whether success
./zipapps.pyz --versionorpython3 zipapps.pyz --version- output:
2020.11.21
-c / --compress- whether to compress the files to reduce file size.
-m / --main- The main function of the application, such as
package.module:function.
- The main function of the application, such as
-o / --output- The path of the output file, defaults to
./app.pyz.
- The path of the output file, defaults to
-p / --python- The path of the Python interpreter to use, defaults to null (no shebang line).
- With the shebang line, you can use
./zipapps.pyzinstead ofpython3 zipapps.pyzfor short.
- the tail
zipappsarg- all the unknown args will be sent to the tail of
pip install. - so you can use
-r requirements.txtor-i https://pypi.org/simplehere.
- all the unknown args will be sent to the tail of
Scene-2: Package your code with requirements as a standalone application, but there are .pyd or .so files.
zipimport could accept .py and .pyc files but reject .pyd and .so files, so we have to unzip them and add the cache folder to sys.path, view more from the Doc.
- Package with
zipappspython3 -m zipapps -c -u psutil psutil
- Check whether success
λ python3 app.pyz -c "import psutil;print(psutil.__file__)"- output:
{CWD}/zipapps_cache/app/psutil/__init__.py{CWD}is the current work directory.- If you didn't set
-u psutil, the output will be{CWD}/app.pyz/psutil/__init__.py
-u / --unzip- choose the files/folders to unzip while running,
- multiple names can be splited by the ",", like
bottle,dir_name, this arg support*forglobusage, - if you are not sure which to unzip, use
*for all, - the files/folders will not be unzipped duplicately if there is an old cache contains the same
_zip_time_file.
python3 -m zipapps -c -a package_name,static_file_path -m package_name.__main__:main -u=* -up "./cache" -r requirements.txtpython3 app.pyz
-up / --unzip-path- If
-u / --unziparg is not null, cache files will be unzipped to the given path. - Defaults to
./zipapps_cache, supportTEMP/HOME/SELFas internal variables. - And you can overwrite it with environment variable
ZIPAPPS_CACHEorUNZIP_PATHwhile running. TEMPmeanstempfile.gettempdir()HOMEmeansPath.home()SELFmeans.pyzfile path
- If
-a / --add / --includes- add some files/folders into zipped file, so you can unzip (or import) them (with the
-uarg) while running. - multiple paths will be splited by ",".
- add some files/folders into zipped file, so you can unzip (or import) them (with the
python3 -m zipapps -c -o venv.pyz -p /usr/bin/python3 -r requirements.txt
python3 venv.pyz script.py- or
./venv.pyz script.py
- or
python3 -m zipapps -c -o venv1.pyz -p /usr/bin/python3 bottle
python3 -m zipapps -c -o venv2.pyz -p /usr/bin/python3 -u AUTO psutil
There are 3 ways to active
PYTHONPATHbelow
- [Easy] After
2020.12.27version, you can use--zipappsarg for otherpyzfiles.
python3 venv1.pyz --zipapps="venv2.pyz" -c "import bottle,psutil;print(bottle.__file__,psutil.__file__)"
- Activate pyz files if unzip is no null
import os
import sys
# reset the unzip cache path to temp dir
os.environ['ZIPAPPS_CACHE'] = 'TEMP/_cache'
# add new import paths
sys.path.insert(0, 'venv1.pyz')
sys.path.insert(0, 'venv2.pyz')
import bottle
# unzip psutil for importing
import ensure_venv2 # or import ensure_zipapps_venv2
import psutil
print(bottle.__file__) # venv1.pyz/bottle.py
print(psutil.__file__) # /tmp/_cache/venv2/psutil/__init__.py- Use the
activatefunction in anyzipappszipped file- or use the
activatefunction ofzipapps.activate_zipappsif zipapps has been installed:-
from zipapps import activate
-
- or use the
import os
import sys
# reset the unzip cache path to temp dir
os.environ['ZIPAPPS_CACHE'] = 'TEMP/_cache'
print(sys.path) # old sys.path including cwd path at index 0
# add PYTHONPATH to import activate_zipapps
sys.path.insert(0, 'venv1.pyz')
print(sys.path) # including `venv1.pyz` at index 0
from activate_zipapps import activate
activate('venv1.pyz')
print(sys.path) # absolute path of `venv1.pyz` has been insert to index 0
activate('venv2.pyz')
print(sys.path) # $(TEMP)/_cache/venv2 and absolute path of `venv2.pyz` addedpython3 -m zipapps -h
Using as the venv zip file example
As you see,
import ensure_zipapps_bottle_envonly works for packaging with a non-nullunziparg.If you don't need to unzip any files/folders,
sys.path.append('app.pyz')is enough.
WARNING: multiple pyz files for venv, you need to ensure each file by special name like import ensure_zipapps_{output_file_name}(such as import ensure_zipapps_bottle) instead of import ensure_zipapps.
'''
zip env as usual:
python3 -m zipapps -u bottle -o bottle_env.pyz bottle
'''
import sys
# add `bottle_env.pyz` as import path
sys.path.append('bottle_env.pyz')
# now import bottle to see where it located
import bottle
print(bottle.__file__)
# yes, it's in the bottle_env.pyz: bottle_env.pyz/bottle.py
# now `import ensure_zipapps` to activate the unzip step
import ensure_zipapps_bottle_env
# reload bottle module to check if the location of bottle changed
import importlib
importlib.reload(bottle)
# now import bottle to see where it located
print(bottle.__file__)
# yes again, it changed to the unzip path: zipapps_cache/bottle_env/bottle.py- How to zip apps with C-Lib requirements for
zipimportingore.pyd,.sofiles?- as https://docs.python.org/3/library/zipimport.html
- we can unzip those packages in temp dirs with
-uargs -
python3 -m zipapps -c -u selectolax selectolax -
python3 app.pyz xxx.py
- How to avoid unlimited unzip cachefolder size growth?
- There is a null file named like
zip-timein zip files and unzip folders - The cache with same
zip-timewill not be unzipped duplicately.
- There is a null file named like
PYTHONPATHbetween zipapps's zip file and global python environment?- If you set
-sppfor strictPYTHONPATH, you will not use the globalPYTHONPATH. - else you will use global libs as a second choice.
- If you set
- How to use multiple venv
pyzfiles in one script?os.environ['UNZIP_PATH'] = '/tmp/unzip_caches'or os.environ['ZIPAPPS_CACHE'] = '/tmp/unzip_caches'
sys.path.insert(0, 'PATH_TO_PYZ_1')sys.path.insert(0, 'PATH_TO_PYZ_2')import ensure_zipapps_{output_name_2}- only if app2 needs to unzip files while running
- Zip pure python code without cache folder while running.
- pure python code will not unzip anything by default.
- Zip files/folders by your choice, and unzip which you want.
- files/libs/folders will be unzip to
-up/--unzip-path, default is./zipapps_cachewhile running. unzip_pathcould use the given variableHOME/TEMP/SELF, for example- HOME/cache => ~/cache folder
- TEMP/cache => /tmp/cache in linux
- or C:\Users\user\AppData\Local\Temp\cache in win32
- SELF/cache => app.pyz/../cache
- SELF equals to the parent folder of pyz file
- or you can reset a new path with environment variable
UNZIP_PATHorZIPAPPS_CACHE- have a try:
- linux:
python3 -m zipapps -u bottle -o bottle_env.pyz bottle&&export UNZIP_PATH=./tmp&&python3 bottle_env.pyz -c "import bottle;print('here is bottle unzip position:', bottle.__file__)" - win:
python3 -m zipapps -u bottle -o bottle_env.pyz bottle&&set UNZIP_PATH=./tmp&&python3 bottle_env.pyz -c "import bottle;print('here is bottle unzip position:', bottle.__file__)"
- linux:
- have a try:
- files/libs/folders will be unzip to
- Zip the dynamic modules (.pyd, .so) which
zipimportnot support.- package with
-ufor these libs.
- package with
- Reuse the unzip cache folder for the same zip timestamp.
zip-timestampwill play as abuild_id
- Use like a
venvor interpreter withpython3 ./env.pyz script.py, script.py will enjoy the PYTHONPATH of env.pyz.- package without
-marg, then run codes inPopen.
- package without
- Fix
psutilImportError of DLL loading.- package with
-ssto usePopeninstead of import directly.
- package with
- Support import
pyzas venv zip file.- activate auto-unzip by
import ensure_zipappsaftersys.path.append("app.pyz")- or active with accurate import
import ensure_zipapps_bottle_envwhile activating multiple environments - or run
python3 ./app.pyz script.pydirectly.
- or active with accurate import
- view the example below for more infomation.
- activate auto-unzip by
- Support compile to
pycfor better performance.- activate compile by
--compileor-cc. - but
__pycache__folder in zip file will not work, - so you can unzip them by
--unzip=xxx, - to check whether
pycworked byimport bottle;print(bottle.__cached__)
- activate compile by
- Support
build_idto skip duplicate builds.- using like
python3 -m zipapps -b requirements.txt -r requirements.txt python3 -m zipapps --build-id=a.py,b.py -r requirements.txtpython3 -m zipapps --build-id=./*.py -r requirements.txtpython3 -m zipapps --build-id=efdd0a5584169cdf791 -r requirements.txtpython3 -m zipapps --build-id=version1.0 -r requirements.txt
- using like
- A simple way to active multiple zipped venv
pyzfiles. - Support auto-check
.pyd/.soto be unzipped. - Combile multiple
pyzfiles.