zipapps


Namezipapps JSON
Version 2024.8.7 PyPI version JSON
download
home_pageNone
SummaryPackage your python code into one zip file, even a virtual environment.
upload_time2024-08-07 15:26:54
maintainerNone
docs_urlNone
authorNone
requires_python>=3.6
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # [zipapps](https://github.com/ClericPy/zipapps)

[![PyPI](https://img.shields.io/pypi/v/zipapps?style=plastic)](https://pypi.org/project/zipapps/)[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/clericpy/zipapps/pythonpackage.yml)](https://github.com/ClericPy/zipapps/actions)![PyPI - Wheel](https://img.shields.io/pypi/wheel/zipapps?style=plastic)![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=zipapps)![PyPI - Downloads](https://img.shields.io/pypi/dm/zipapps?style=plastic)![PyPI - License](https://img.shields.io/pypi/l/zipapps?style=plastic)

[Changelogs](https://github.com/ClericPy/zipapps/blob/master/changelog.md)

`zipapps` is a **pure-python** library, to package your python code into a single zip file with its dependencies.

Depends on [PEP441](https://www.python.org/dev/peps/pep-0441/) + [zipapp](https://docs.python.org/3/library/zipapp.html) + [zipimport](https://docs.python.org/3/library/zipimport.html).

# What is the `.pyz`?

`.pyz` to `Python` is like `.jar` to `Java`.

They are both zip archive files which aggregate many packages and associated metadata and resources (text, images, etc.) into one file for distribution.

All you need is the **Python Interpreter** as the runtime environment.

So, what could `zipapps` be?

1. `packaging tool`
    > compress your package folder into a zip file.
2. `single-file virtual environment`
    > a portable site-packages.
3. `dependences installer`
    > lazy install requirements while first running.
4. `set of import-path`
    > add many `venv.pyz` files to PYTHONPATH automatically.
5. `requirements.txt freezing toolkit`
    > use `venv` to freeze your pip packages.

> PS: The pyz extension can be modified to any character you want, such as `.py` and `.zip`.

# Install & Quick Start

> pip install zipapps -U

## 1. Source code without dependences

1. add your source code into the zip file, and set the entrypoint with `-m`
   1. > python3 -m zipapps -c -a entry.py -m entry:main -o app.pyz
      1. `entry.py` could be a package `package_name`
      2. `-m` format is `package.module:function`
2. run app.pyz
   1. > python3 app.pyz

## 2. Source code with dependences

1. zipapps with requirements
   
   1. > python3 -m zipapps -c -a entry.py -m entry:main -o app.pyz bottle
      1. `bottle` is a pure-python lib which may not be unzipped
         1. `-u AUTO` or `-u=*` should be set for some `.so/.pyd` libs
            1. such as `psutil`
            2. notice that the `-u=*` != `-u *`
   2. you don't need to install requirements at running

      1. ensure the compatibility of the system environment and python version
      2. or add `-d` of `lazy install` mode to skip the compatibility problem
         1. but comes a long-time `pip install` process at the first running.

2. run app.pyz
   
   1. > python3 app.pyz
   2. libs with `.pyd/.so` caches will be unzipped to the `./zipapps_cache/app` by `-u AUTO`

## 3. Virtual environments

1. zipapps with requirements
   
   1. > python3 -m zipapps -c -u AUTO -o venv.pyz -r requirements.txt

2. run entry.py with venv.pyz
   
   1. > python3 venv.pyz entry.py
   2. the cache will be unzipped to `./zipapps_cache/venv` for `-u` is not null

## 4. Activate the `.pyz` environment

1. `import zipimport; zipimport.zipimporter('bottle.pyz').load_module("ensure_zipapps")`
   1. automatically unzip cache, and add the path to sys.path
   2. it can be run multiple times
2. if they are all pure-python code and **no need to decompress**
   1. `impory sys; sys.path.insert(0, "bottle.pyz")`


# Command line usage

![image](https://github.com/ClericPy/zipapps/raw/master/args.png)

## Build Args

**most common args:**

- `-c`
  - to compress files, only for python3.7+.
- `-a xxx.py`
  - to add some files/folders into the zipped file.
- `-u=AUTO`
  - **Recommended**
  - auto unzip the .pyd / .so files
    - or `-u=*` to unzip all the files
- `-r requirements.txt`
  - install requirements with `pip install`
- `-o my_app.pyz`
  - output the zipped file as given path
- `-m app.__main__:main`
  - entry point
- `-p /usr/bin/python3`
  - set the `shebang` line
- `-d`
  - **Recommended**
  - requirements will be installed with `pip` while first running in the lazy install mode
  - zip file size will be very small, and the default unzip path is `SELF/zipapps_cache/`
- `--clear-zipapps-cache`, `-czc`
  - Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files.

Details: 

> python3 -m zipapps -h

1. `-h, --help`
   1. **show the simple doc**
2. `--includes, --add, -a`
   1. The given paths will be copied to `cache_path` while packaging, which can be used while running. The path strings will be splited by ",".
      1. such as `my_package_dir,my_module.py,my_config.json`
      2. often used for libs not from `pypi` or some special config files
   2. the `output` arg of `zipapps.create_app`
3. `--output, -o`
   1. The path of the output file, defaults to `app.pyz`.
   2. the `output` arg of `zipapps.create_app`
4. `--python, -p`
   1. The path of the Python interpreter which will be set as the `shebang line`, defaults to `None`.
      1. with shebang `/usr/bin/python3` you can run app with `./app.pyz` directly, no need for `python3 app.pyz`
   2. the `interpreter` arg of `zipapps.create_app`
5. `--main, -m`
   1. The entry point function of the application, the `valid format` is:
      1. `package.module:function`
      2. `package.module`
      3. `module:function`
      4. `package`
   2. the `main` arg of `zipapps.create_app`
   3. WARNING: If the `--main` arg is set, `python3 app.pyz` will not be able to used as venv like `python3 app.pyz xxx.py`
6. `--compress, -c`
   1. `Boolean` value, compress files with the deflate method or not.
   2. the `compressed` arg of `zipapps.create_app`
7. `--unzip, -u`
   1. The names which need to be unzipped while running, splited by "," `without ext`, such as `bottle,aiohttp`, or the complete path like `bin/bottle.py,temp.py`. For `.so/.pyd` files(which can not be loaded by zipimport), or packages with operations of static files.
      1. if unzip is set to "*", then will unzip all files and folders.
      2. if unzip is set to **AUTO**, then will add the `.pyd` and `.so` files automatically.
   2. Can be overwrite with environment variable `ZIPAPPS_UNZIP`
   3. the `unzip` arg of `zipapps.create_app`
8. `--unzip-exclude, -ue`
   1. The opposite of `--unzip` / `-u` which will not be unzipped, should be used with `--unzip` / `-u`.
   2. Can be overwrite with environment variable `ZIPAPPS_UNZIP_EXCLUDE`
9. `--unzip-path, -up`
   3. If `unzip` arg is not null, cache files will be unzipped to the given path while running. Defaults to `zipapps_cache`, support some internal variables as runtime args:
      1. `$TEMP/$HOME/$SELF/$PID/$CWD` as prefix, for example `$HOME/zipapps_cache`
         1. `TEMP` means `tempfile.gettempdir()`
         2. `HOME` means `Path.home()`
         3. `SELF` means `.pyz` file path.
         4. `$PID` means `os.getpid()`
         5. `$CWD` means `Path.cwd()`
      2. And you can also **overwrite** it with environment variables:
         1. `ZIPAPPS_CACHE` or `UNZIP_PATH`
   4. the `unzip_path` arg of `zipapps.create_app`
10. `-cc, --pyc, --compile, --compiled`
    1. Compile .py to .pyc for fast import, but zipapp does not work unless you unzip it(so NOT very useful).
    2. the `compiled` arg of `zipapps.create_app`
11. ` --cache-path, --source-dir, -cp`
    1. The cache path of zipapps to store site-packages and `includes` files. If not set, will create and clean-up in TEMP dir automately.
    2. the `cache_path` arg of `zipapps.create_app`
12. `--shell, -s`
    1. Only while `main` is not set, used for shell=True in `subprocess.run`.
       1. *very rarely used*, because extra sub-process is not welcome
    2. the `shell` arg of `zipapps.create_app`
13. `--main-shell, -ss`
    1. Only for `main` is not null, call `main` with `subprocess.Popen`: `python -c "import a.b;a.b.c()"`. This is used for `psutil` ImportError of DLL load.
       1. *very rarely used* too
    2. the `main_shell` arg of `zipapps.create_app`
14. `--strict-python-path, -spp`
    1. `Boolean` value. Ignore global PYTHONPATH, only use `zipapps_cache` and `app.pyz`.
    2. the `ignore_system_python_path` arg of `zipapps.create_app`
15. `-b, --build-id`
    1. The string to skip duplicate builds, it can be the paths of files/folders which splited by ",", then the modify time will be used as build_id. If build_id contains `*`, will use `glob` function to get paths. For example, you can set requirements.txt as your build_id by `python3 -m zipapps -b requirements.txt -r requirements.txt` when you use pyz as venv.
       1. *very rarely used* too too
    2. the `build_id` arg of `zipapps.create_app`
16. `--zipapps, --env-paths`
    1. Default `--zipapps` arg if it is not given while running. Support $TEMP/$HOME/$SELF/$PID/$CWD prefix.
17. `--delay, -d, --lazy-pip, --lazy-install, --lazy-pip-install`
    1. Install packages with pip while first running, which means requirements will not be install into pyz file.
18. `--ensure-pip`
    1. Add the ensurepip package to your pyz file, works for **embed-python**(windows) or other python versions without `pip` installed but `lazy-install` mode is enabled. [EXPERIMENTAL]
19. `--layer-mode`
    1. Layer mode for the `serverless` use case, `__main__.py / ensure_zipapps.py / activate_zipapps.py` files will not be set in this mode.
    2. `--layer-mode-prefix`
       1. Only work while `--layer-mode` is set, will move the files in the given prefix folder.
20. `--clear-zipapps-cache, -czc`
    1. Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files.
21. `--clear-zipapps-self, -czs`
    1. Clear the zipapps pyz file self after running.
22. `--chmod`
    1. os.chmod(int(chmod, 8)) for unzip files with `--chmod=777`
        1.  unix-like system only
23. `--dump-config`
    1. Dump zipapps build args into JSON string.
       1. A file path needed and `-` means stdout.
24. `--load-config`
    1. Load zipapps build args from a JSON file.
25. `--freeze-reqs`
    1.  Freeze package versions of pip args with venv, output to the given file path.
        1.  `-` equals to `stdout`
        2.  logs will be redirect to `stderr`
    2.  Based on `pip` + `venv`
        1.  work folder is `tempfile.TemporaryDirectory`, prefix='zipapps_'
26. all the other (or `unknown`) args will be used by `pip install`
    1. such as `-r requirements.txt`
    2. such as `bottle aiohttp`
    3. the `pip_args` arg of `zipapps.create_app`

## Runtime Args

> available args while the `.pyz` is running

1. `--zipapps`
   1. including some other pyz into PYTHONPATH
   2. often be used as `multiple venv combination`
   3. for example
      1. build
         1. `python3 -m zipapps -o six.pyz six`
         2. `python3 -m zipapps -o psutil.pyz -u AUTO psutil`
         3. `python3 -m zipapps -o bottle.pyz bottle`
      2. run
         1. `python3 six.pyz --zipapps=psutil.pyz,bottle.pyz -c "import psutil, bottle"`
2. `--activate-zipapps` / `--ensure-zipapps`
   1. to ensure the zipapps_cache folder but do nothing
3. use environment variables to reset build args while running, and custom it with `ENV_ALIAS` arg
    1.  the upper names are environment variables
    2.  
            'unzip': 'ZIPAPPS_UNZIP',
            'unzip_exclude': 'ZIPAPPS_UNZIP_EXCLUDE',
            'unzip_path': 'ZIPAPPS_CACHE',
            'ignore_system_python_path': 'STRICT_PYTHON_PATH',
            'python_version_slice': 'PYTHON_VERSION_SLICE',
            'clear_zipapps_cache': 'CLEAR_ZIPAPPS_CACHE',
            'clear_zipapps_self': 'CLEAR_ZIPAPPS_SELF',
            'unzip_chmod': 'UNZIP_CHMOD',

# When to Use it?

1. Package your code(package or model) into one zipped file. 
   
   1. Pure python code without any 3rd-party dependencies.
   
   2. Python code with 3rd-party dependencies installed together.
   
   3. Python code with requirements be not installed until running. 
      
      1. [**Recommended**] The `lazy install` mode by the arg `-d`.
      
      2. The dependences will be installed at the first running(only once).
      
      3. This is `cross-platform` and `cross-python-version` for their independent cache paths.

2. Run with python interpreter from the `venv` path.
   
   1. which means the requirements(need to be unzipped) will be installed to the `venv` folder, not in `pyz` file.
   2. **build** your package into one `pyz` file with `-m package.module:function -p /venv/bin/python`.
   3. **run** the `pyz` file with `/venv/bin/python app.pyz` or `./app.pyz`.

3. Rapidly deploy stateless applications
   
   1. `Serverless`
      1. with a ready layer
   2. `Docker`
      1. only built once for a Python environment
      2. `wget http://S3_PATH/app.pyz && python3 app.pyz`
   3. `Spot instances`
      1. AWS or Aliyun
   4. `Hadoop-Streaming`
      1. mapper & reducer scripts

4. Simple deployment towards different servers with `jenkins`, or other CI/CD tools.
   
   1. Easy to uploads a clean `standalone` zip file.

5. Share the `app.pyz`to your friends
   
   1. someone has python installed
      
      1. or embedded python
      
      2. or use nuitka
         
         1. [zipapps with nuitka](https://github.com/ClericPy/zipapps/issues/11)

6. Use as a requirements zip path, or some `venv` usages.
   
   1. inner the code
      
      1. `import sys;sys.path.insert(0, 'app.pyz')` 
      
      2. with .so/.pyd?
         
         1. `import activate_zipapps`
   
   2. or run it directly
      
      1. `python3 app.pyz script.py`

7. Other usages need to be found, and enjoy yourself

# Advanced Usage

Inspired by [shiv](https://github.com/linkedin/shiv) and with the differences.

1. `zipapps` may not always create the cache folder.
   1. `pure-python` dependencies can be import directly without unzipped.
   2. unless your package includes the C language-based libraries or dynamic modules(`.so/.pyd`), such as `psutil`.
      1. use the arg `-u=AUTO` or `-u=*`
2. The default cache path is `./zipapps_cache` instead of the `HOME` path.
3. One app name create cache folder only once.
4. You can install requirements with `pip` while first running(not packaging) by `lazy install` mode
   1. reducing your `.pyz` file size.
      1. cross-platform and cross-python-version
   2. `python -m zipapps -c -d -a your-package -r requirements.txt`
5. Mix multiple `venv.pyz` files together.
   1. `python -m app.pyz --zipapps=bottle.pyz,requests.pyz`
6. **Freeze** your requirements.txt
   1. `python -m zipapps --freeze-reqs=requirements.lock -r requirements.txt`

<details>

<summary> <b>Click here read more</b> </summary>

## 1. Package your script file with only built-ins functions.

1.1 Code of `script.py`

```python
print('ok')
```

1.2 build the `app.pyz`

> python3 -m zipapps -c -a script.py -m script -p /usr/bin/python3

1.3 run this app

> python3 app.pyz

or

> ./app.pyz

ouput

    ok

Details:

    -c:
        compress files, 7.6KB => 3.3KB
    -a:
        add the script file to app.pyz, so you can use it while running
    -m:
        set the entry_point, also can be set as `-m script:main` as long as you has the main function
    -p:
        set the shebang line, so you can use `./app.pyz` instead of `python3 app.pyz`

## 2. Package your package folder into one zip file.

2.1 The package `example` and the code of `__main__.py`

    └── example
        ├── __init__.py
        └── __main__.py

```python
def main():
    print('ok')


if __name__ == "__main__":
    main()
```

2.2 build the `example.pyz`

> python3 -m zipapps -c -a example -o example.pyz -m example.__main__:main -p /usr/bin/python3

2.3 Run with `python3 example.pyz` or `./example.pyz`

output

    ok

Details:

    -m:
        set the entry_point with format like `package.model:function`
    -o:
        set the output file path, you can set it some other paths like `/home/centos/example.abc` and run with `python3 /home/centos/example.abc`
    no more new args.

## 3. Package your code with requirements (bottle).

3.1 The package `example` and the code of `__main__.py`

        └── example
            ├── __init__.py
            └── __main__.py

```python
def main():
    import bottle
    print(bottle.__version__)


if __name__ == "__main__":
    main()
```

3.2 build the `example.pyz` with requirements installed

> python3 -m zipapps -c -a example -o example.pyz -m example.__main__:main bottle

3.3 Run with `python3 example.pyz` or `./example.pyz`

Output

    0.12.19

Details:

    bottle:
        all the unhandled args (like `bottle`) will be used to `pip install`, so you can write `bottle` in requirements.txt and use like `-r requirements.txt`

**WARNING**: if the requirements have `.pyd/.so` files, you should unzip them while running, and the pure python libs like `bottle` or `requests`  no need to unzip anything. Read the 4th paragraph for more info.

## 4. Package your code with the requirements which includes `.pyd/.so` files.

4.1 The package `example` and the code of `__main__.py`

    └── example
        ├── __init__.py
        └── __main__.py

```python
def main():
    import psutil
    print(psutil.__version__)


if __name__ == "__main__":
    main()
```

4.2 build the `example.pyz` with requirements installed

> python3 -m zipapps -c -a example -o example.pyz -m example.__main__:main -u AUTO -up TEMP/cache psutil

4.3 Run with `python3 example.pyz` or `./example.pyz`

Output

    5.8.0

Details:

    -u:
        means the file or folder names you want to unzip while running. Here is the `AUTO`, will unzip the psutil package because of its .pyd or .so files included.
    -up:
        the unzip path of cache folder. $TEMP/$HOME/$SELF/$PID/$CWD are the built-in runtime args, but for the stable usage you can ignore this arg then use `./zipapps_cache/example`. The cache will be refreshed while you rebuild this pyz.

WARNING: unzip path can be overwrited by `export ZIPAPPS_CACHE=./xxx` or `export UNZIP_PATH=./xxx` while running.

## 5. Package the requirements like a virtual environment without entry_point.

5.1 Code of `script.py`

```python
import bottle, requests
print(bottle.__version__, requests.__version__)
```

5.2 build the `venv.pyz` 

> python3 -m zipapps -c -o venv.pyz -p /usr/bin/python3 bottle requests

5.3 Some use cases

5.3.1 use the `venv.pyz` like a middleware

> python3 venv.pyz script.py

5.3.2 use the `venv.pyz` like the interpreter

> ./venv.pyz script.py

even like is also valid

> `python3 venv.pyz -c "import bottle,requests;print(bottle.__version__, requests.__version__)"`

5.3.3 use the `bottle` lib of `venv.pyz` in your normal code

```python
import sys
sys.path.append('path_to_venv/venv.pyz')
import bottle

print(bottle.__file__)
```

5.3.3 use the `pstuil` lib of `venv.pyz` in other normal code

> python3 -m zipapps -c -o venv.pyz psutil

```python
import sys
sys.path.append('path_to_venv/psutil_venv.pyz')
# need to activate the unzip action, there are 2 ways for the `.so/.pyd` libs
# 1. use the default activate name
import activate_zipapps
# 2. use a distinct lib name with file name for another venv file
sys.path.append('path_to_venv/lxml_venv.pyz')
import ensure_lxml_venv
# 2.1 or the old name
# import ensure_zipapps_lxml_venv


import psutil
import lxml

print(psutil.__file__)
print(lxml.__file__)
```

Output

    0.12.19 2.25.1

Details:

    No `-m` arg here, then the pyz file will do like an interpreter which contains the installed requirements.
    
    So you can use it like this:
    > python3 venv.pyz
    >>> import bottle
    >>> bottle.__file__

## 6. Using multiple venv pyz files for your pyz model.

6.1 Here is `script.py` again

```python
import bottle, requests
print(bottle.__version__, requests.__version__)
```

6.2 Build the `script.pyz`

> python3 -m zipapps -c -o script.pyz -a script.py -m script requests

6.3 Build the `requests.pyz` and `bottle.pyz` respectively

> python3 -m zipapps -c -o requests.pyz requests
> 
> python3 -m zipapps -c -o bottle.pyz bottle

6.4 And now run the `script.pyz` with two requirements

> python3 script.pyz --zipapps=bottle.pyz,requests.pyz

Output

    0.12.19 2.25.1

Details:

    --zipapps:
        This arg will help you run some zipapp with given venv.pyz files, the paths is separated by commas.

## 7. Package your code with lazy install mode, for a attempt of cross-platform.

7.1 Here is `script.py` again

```python
import six
print(six.__file__)
```

7.2 Build the `script.pyz`, this is very fast without downloading and installing 3rd packages.

> python3 -m zipapps -c -o script.pyz -a script.py -m script -d six

7.3 Run this `.pyz` file, and the requirements will be installed while first running.

> python3 script.pyz

Output

    Looking in indexes: https://pypi.xxx.com/simple/
    Collecting six
    Using cached https://xxx/packages/ee/ff/xxxx/six-1.15.0-py2.py3-none-any.whl (10 kB)
    Installing collected packages: six
    Successfully installed six-1.15.0
    /tmp/zipapps_cache/script/_zipapps_lazy_pip/3.8/Linux/six.py

Details:

    -d:
        Lazy install mode is useful for distributing your cross-platform apps.

</details>

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "zipapps",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": null,
    "author": null,
    "author_email": "ClericPy <clericpy@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/55/f8/c9c91f79479727f93fb8b8c1b77960fd4d3b1cd4590a775e53bbb57783ca/zipapps-2024.8.7.tar.gz",
    "platform": null,
    "description": "# [zipapps](https://github.com/ClericPy/zipapps)\n\n[![PyPI](https://img.shields.io/pypi/v/zipapps?style=plastic)](https://pypi.org/project/zipapps/)[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/clericpy/zipapps/pythonpackage.yml)](https://github.com/ClericPy/zipapps/actions)![PyPI - Wheel](https://img.shields.io/pypi/wheel/zipapps?style=plastic)![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=zipapps)![PyPI - Downloads](https://img.shields.io/pypi/dm/zipapps?style=plastic)![PyPI - License](https://img.shields.io/pypi/l/zipapps?style=plastic)\n\n[Changelogs](https://github.com/ClericPy/zipapps/blob/master/changelog.md)\n\n`zipapps` is a **pure-python** library, to package your python code into a single zip file with its dependencies.\n\nDepends on [PEP441](https://www.python.org/dev/peps/pep-0441/) + [zipapp](https://docs.python.org/3/library/zipapp.html) + [zipimport](https://docs.python.org/3/library/zipimport.html).\n\n# What is the `.pyz`?\n\n`.pyz` to `Python` is like `.jar` to `Java`.\n\nThey are both zip archive files which aggregate many packages and associated metadata and resources (text, images, etc.) into one file for distribution.\n\nAll you need is the **Python Interpreter** as the runtime environment.\n\nSo, what could `zipapps` be?\n\n1. `packaging tool`\n    > compress your package folder into a zip file.\n2. `single-file virtual environment`\n    > a portable site-packages.\n3. `dependences installer`\n    > lazy install requirements while first running.\n4. `set of import-path`\n    > add many `venv.pyz` files to PYTHONPATH automatically.\n5. `requirements.txt freezing toolkit`\n    > use `venv` to freeze your pip packages.\n\n> PS: The pyz extension can be modified to any character you want, such as `.py` and `.zip`.\n\n# Install & Quick Start\n\n> pip install zipapps -U\n\n## 1. Source code without dependences\n\n1. add your source code into the zip file, and set the entrypoint with `-m`\n   1. > python3 -m zipapps -c -a entry.py -m entry:main -o app.pyz\n      1. `entry.py` could be a package `package_name`\n      2. `-m` format is `package.module:function`\n2. run app.pyz\n   1. > python3 app.pyz\n\n## 2. Source code with dependences\n\n1. zipapps with requirements\n   \n   1. > python3 -m zipapps -c -a entry.py -m entry:main -o app.pyz bottle\n      1. `bottle` is a pure-python lib which may not be unzipped\n         1. `-u AUTO` or `-u=*` should be set for some `.so/.pyd` libs\n            1. such as `psutil`\n            2. notice that the `-u=*` != `-u *`\n   2. you don't need to install requirements at running\n\n      1. ensure the compatibility of the system environment and python version\n      2. or add `-d` of `lazy install` mode to skip the compatibility problem\n         1. but comes a long-time `pip install` process at the first running.\n\n2. run app.pyz\n   \n   1. > python3 app.pyz\n   2. libs with `.pyd/.so` caches will be unzipped to the `./zipapps_cache/app` by `-u AUTO`\n\n## 3. Virtual environments\n\n1. zipapps with requirements\n   \n   1. > python3 -m zipapps -c -u AUTO -o venv.pyz -r requirements.txt\n\n2. run entry.py with venv.pyz\n   \n   1. > python3 venv.pyz entry.py\n   2. the cache will be unzipped to `./zipapps_cache/venv` for `-u` is not null\n\n## 4. Activate the `.pyz` environment\n\n1. `import zipimport; zipimport.zipimporter('bottle.pyz').load_module(\"ensure_zipapps\")`\n   1. automatically unzip cache, and add the path to sys.path\n   2. it can be run multiple times\n2. if they are all pure-python code and **no need to decompress**\n   1. `impory sys; sys.path.insert(0, \"bottle.pyz\")`\n\n\n# Command line usage\n\n![image](https://github.com/ClericPy/zipapps/raw/master/args.png)\n\n## Build Args\n\n**most common args:**\n\n- `-c`\n  - to compress files, only for python3.7+.\n- `-a xxx.py`\n  - to add some files/folders into the zipped file.\n- `-u=AUTO`\n  - **Recommended**\n  - auto unzip the .pyd / .so files\n    - or `-u=*` to unzip all the files\n- `-r requirements.txt`\n  - install requirements with `pip install`\n- `-o my_app.pyz`\n  - output the zipped file as given path\n- `-m app.__main__:main`\n  - entry point\n- `-p /usr/bin/python3`\n  - set the `shebang` line\n- `-d`\n  - **Recommended**\n  - requirements will be installed with `pip` while first running in the lazy install mode\n  - zip file size will be very small, and the default unzip path is `SELF/zipapps_cache/`\n- `--clear-zipapps-cache`, `-czc`\n  - Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files.\n\nDetails: \n\n> python3 -m zipapps -h\n\n1. `-h, --help`\n   1. **show the simple doc**\n2. `--includes, --add, -a`\n   1. The given paths will be copied to `cache_path` while packaging, which can be used while running. The path strings will be splited by \",\".\n      1. such as `my_package_dir,my_module.py,my_config.json`\n      2. often used for libs not from `pypi` or some special config files\n   2. the `output` arg of `zipapps.create_app`\n3. `--output, -o`\n   1. The path of the output file, defaults to `app.pyz`.\n   2. the `output` arg of `zipapps.create_app`\n4. `--python, -p`\n   1. The path of the Python interpreter which will be set as the `shebang line`, defaults to `None`.\n      1. with shebang `/usr/bin/python3` you can run app with `./app.pyz` directly, no need for `python3 app.pyz`\n   2. the `interpreter` arg of `zipapps.create_app`\n5. `--main, -m`\n   1. The entry point function of the application, the `valid format` is:\n      1. `package.module:function`\n      2. `package.module`\n      3. `module:function`\n      4. `package`\n   2. the `main` arg of `zipapps.create_app`\n   3. WARNING: If the `--main` arg is set, `python3 app.pyz` will not be able to used as venv like `python3 app.pyz xxx.py`\n6. `--compress, -c`\n   1. `Boolean` value, compress files with the deflate method or not.\n   2. the `compressed` arg of `zipapps.create_app`\n7. `--unzip, -u`\n   1. The names which need to be unzipped while running, splited by \",\" `without ext`, such as `bottle,aiohttp`, or the complete path like `bin/bottle.py,temp.py`. For `.so/.pyd` files(which can not be loaded by zipimport), or packages with operations of static files.\n      1. if unzip is set to \"*\", then will unzip all files and folders.\n      2. if unzip is set to **AUTO**, then will add the `.pyd` and `.so` files automatically.\n   2. Can be overwrite with environment variable `ZIPAPPS_UNZIP`\n   3. the `unzip` arg of `zipapps.create_app`\n8. `--unzip-exclude, -ue`\n   1. The opposite of `--unzip` / `-u` which will not be unzipped, should be used with `--unzip` / `-u`.\n   2. Can be overwrite with environment variable `ZIPAPPS_UNZIP_EXCLUDE`\n9. `--unzip-path, -up`\n   3. If `unzip` arg is not null, cache files will be unzipped to the given path while running. Defaults to `zipapps_cache`, support some internal variables as runtime args:\n      1. `$TEMP/$HOME/$SELF/$PID/$CWD` as prefix, for example `$HOME/zipapps_cache`\n         1. `TEMP` means `tempfile.gettempdir()`\n         2. `HOME` means `Path.home()`\n         3. `SELF` means `.pyz` file path.\n         4. `$PID` means `os.getpid()`\n         5. `$CWD` means `Path.cwd()`\n      2. And you can also **overwrite** it with environment variables:\n         1. `ZIPAPPS_CACHE` or `UNZIP_PATH`\n   4. the `unzip_path` arg of `zipapps.create_app`\n10. `-cc, --pyc, --compile, --compiled`\n    1. Compile .py to .pyc for fast import, but zipapp does not work unless you unzip it(so NOT very useful).\n    2. the `compiled` arg of `zipapps.create_app`\n11. ` --cache-path, --source-dir, -cp`\n    1. The cache path of zipapps to store site-packages and `includes` files. If not set, will create and clean-up in TEMP dir automately.\n    2. the `cache_path` arg of `zipapps.create_app`\n12. `--shell, -s`\n    1. Only while `main` is not set, used for shell=True in `subprocess.run`.\n       1. *very rarely used*, because extra sub-process is not welcome\n    2. the `shell` arg of `zipapps.create_app`\n13. `--main-shell, -ss`\n    1. Only for `main` is not null, call `main` with `subprocess.Popen`: `python -c \"import a.b;a.b.c()\"`. This is used for `psutil` ImportError of DLL load.\n       1. *very rarely used* too\n    2. the `main_shell` arg of `zipapps.create_app`\n14. `--strict-python-path, -spp`\n    1. `Boolean` value. Ignore global PYTHONPATH, only use `zipapps_cache` and `app.pyz`.\n    2. the `ignore_system_python_path` arg of `zipapps.create_app`\n15. `-b, --build-id`\n    1. The string to skip duplicate builds, it can be the paths of files/folders which splited by \",\", then the modify time will be used as build_id. If build_id contains `*`, will use `glob` function to get paths. For example, you can set requirements.txt as your build_id by `python3 -m zipapps -b requirements.txt -r requirements.txt` when you use pyz as venv.\n       1. *very rarely used* too too\n    2. the `build_id` arg of `zipapps.create_app`\n16. `--zipapps, --env-paths`\n    1. Default `--zipapps` arg if it is not given while running. Support $TEMP/$HOME/$SELF/$PID/$CWD prefix.\n17. `--delay, -d, --lazy-pip, --lazy-install, --lazy-pip-install`\n    1. Install packages with pip while first running, which means requirements will not be install into pyz file.\n18. `--ensure-pip`\n    1. Add the ensurepip package to your pyz file, works for **embed-python**(windows) or other python versions without `pip` installed but `lazy-install` mode is enabled. [EXPERIMENTAL]\n19. `--layer-mode`\n    1. Layer mode for the `serverless` use case, `__main__.py / ensure_zipapps.py / activate_zipapps.py` files will not be set in this mode.\n    2. `--layer-mode-prefix`\n       1. Only work while `--layer-mode` is set, will move the files in the given prefix folder.\n20. `--clear-zipapps-cache, -czc`\n    1. Clear the zipapps cache folder after running, but maybe failed for .pyd/.so files.\n21. `--clear-zipapps-self, -czs`\n    1. Clear the zipapps pyz file self after running.\n22. `--chmod`\n    1. os.chmod(int(chmod, 8)) for unzip files with `--chmod=777`\n        1.  unix-like system only\n23. `--dump-config`\n    1. Dump zipapps build args into JSON string.\n       1. A file path needed and `-` means stdout.\n24. `--load-config`\n    1. Load zipapps build args from a JSON file.\n25. `--freeze-reqs`\n    1.  Freeze package versions of pip args with venv, output to the given file path.\n        1.  `-` equals to `stdout`\n        2.  logs will be redirect to `stderr`\n    2.  Based on `pip` + `venv`\n        1.  work folder is `tempfile.TemporaryDirectory`, prefix='zipapps_'\n26. all the other (or `unknown`) args will be used by `pip install`\n    1. such as `-r requirements.txt`\n    2. such as `bottle aiohttp`\n    3. the `pip_args` arg of `zipapps.create_app`\n\n## Runtime Args\n\n> available args while the `.pyz` is running\n\n1. `--zipapps`\n   1. including some other pyz into PYTHONPATH\n   2. often be used as `multiple venv combination`\n   3. for example\n      1. build\n         1. `python3 -m zipapps -o six.pyz six`\n         2. `python3 -m zipapps -o psutil.pyz -u AUTO psutil`\n         3. `python3 -m zipapps -o bottle.pyz bottle`\n      2. run\n         1. `python3 six.pyz --zipapps=psutil.pyz,bottle.pyz -c \"import psutil, bottle\"`\n2. `--activate-zipapps` / `--ensure-zipapps`\n   1. to ensure the zipapps_cache folder but do nothing\n3. use environment variables to reset build args while running, and custom it with `ENV_ALIAS` arg\n    1.  the upper names are environment variables\n    2.  \n            'unzip': 'ZIPAPPS_UNZIP',\n            'unzip_exclude': 'ZIPAPPS_UNZIP_EXCLUDE',\n            'unzip_path': 'ZIPAPPS_CACHE',\n            'ignore_system_python_path': 'STRICT_PYTHON_PATH',\n            'python_version_slice': 'PYTHON_VERSION_SLICE',\n            'clear_zipapps_cache': 'CLEAR_ZIPAPPS_CACHE',\n            'clear_zipapps_self': 'CLEAR_ZIPAPPS_SELF',\n            'unzip_chmod': 'UNZIP_CHMOD',\n\n# When to Use it?\n\n1. Package your code(package or model) into one zipped file. \n   \n   1. Pure python code without any 3rd-party dependencies.\n   \n   2. Python code with 3rd-party dependencies installed together.\n   \n   3. Python code with requirements be not installed until running. \n      \n      1. [**Recommended**] The `lazy install` mode by the arg `-d`.\n      \n      2. The dependences will be installed at the first running(only once).\n      \n      3. This is `cross-platform` and `cross-python-version` for their independent cache paths.\n\n2. Run with python interpreter from the `venv` path.\n   \n   1. which means the requirements(need to be unzipped) will be installed to the `venv` folder, not in `pyz` file.\n   2. **build** your package into one `pyz` file with `-m package.module:function -p /venv/bin/python`.\n   3. **run** the `pyz` file with `/venv/bin/python app.pyz` or `./app.pyz`.\n\n3. Rapidly deploy stateless applications\n   \n   1. `Serverless`\n      1. with a ready layer\n   2. `Docker`\n      1. only built once for a Python environment\n      2. `wget http://S3_PATH/app.pyz && python3 app.pyz`\n   3. `Spot instances`\n      1. AWS or Aliyun\n   4. `Hadoop-Streaming`\n      1. mapper & reducer scripts\n\n4. Simple deployment towards different servers with `jenkins`, or other CI/CD tools.\n   \n   1. Easy to uploads a clean `standalone` zip file.\n\n5. Share the `app.pyz`to your friends\n   \n   1. someone has python installed\n      \n      1. or embedded python\n      \n      2. or use nuitka\n         \n         1. [zipapps with nuitka](https://github.com/ClericPy/zipapps/issues/11)\n\n6. Use as a requirements zip path, or some `venv` usages.\n   \n   1. inner the code\n      \n      1. `import sys;sys.path.insert(0, 'app.pyz')` \n      \n      2. with .so/.pyd?\n         \n         1. `import activate_zipapps`\n   \n   2. or run it directly\n      \n      1. `python3 app.pyz script.py`\n\n7. Other usages need to be found, and enjoy yourself\n\n# Advanced Usage\n\nInspired by [shiv](https://github.com/linkedin/shiv) and with the differences.\n\n1. `zipapps` may not always create the cache folder.\n   1. `pure-python` dependencies can be import directly without unzipped.\n   2. unless your package includes the C language-based libraries or dynamic modules(`.so/.pyd`), such as `psutil`.\n      1. use the arg `-u=AUTO` or `-u=*`\n2. The default cache path is `./zipapps_cache` instead of the `HOME` path.\n3. One app name create cache folder only once.\n4. You can install requirements with `pip` while first running(not packaging) by `lazy install` mode\n   1. reducing your `.pyz` file size.\n      1. cross-platform and cross-python-version\n   2. `python -m zipapps -c -d -a your-package -r requirements.txt`\n5. Mix multiple `venv.pyz` files together.\n   1. `python -m app.pyz --zipapps=bottle.pyz,requests.pyz`\n6. **Freeze** your requirements.txt\n   1. `python -m zipapps --freeze-reqs=requirements.lock -r requirements.txt`\n\n<details>\n\n<summary> <b>Click here read more</b> </summary>\n\n## 1. Package your script file with only built-ins functions.\n\n1.1 Code of `script.py`\n\n```python\nprint('ok')\n```\n\n1.2 build the `app.pyz`\n\n> python3 -m zipapps -c -a script.py -m script -p /usr/bin/python3\n\n1.3 run this app\n\n> python3 app.pyz\n\nor\n\n> ./app.pyz\n\nouput\n\n    ok\n\nDetails:\n\n    -c:\n        compress files, 7.6KB => 3.3KB\n    -a:\n        add the script file to app.pyz, so you can use it while running\n    -m:\n        set the entry_point, also can be set as `-m script:main` as long as you has the main function\n    -p:\n        set the shebang line, so you can use `./app.pyz` instead of `python3 app.pyz`\n\n## 2. Package your package folder into one zip file.\n\n2.1 The package `example` and the code of `__main__.py`\n\n    \u2514\u2500\u2500 example\n        \u251c\u2500\u2500 __init__.py\n        \u2514\u2500\u2500 __main__.py\n\n```python\ndef main():\n    print('ok')\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\n2.2 build the `example.pyz`\n\n> python3 -m zipapps -c -a example -o example.pyz -m example.__main__:main -p /usr/bin/python3\n\n2.3 Run with `python3 example.pyz` or `./example.pyz`\n\noutput\n\n    ok\n\nDetails:\n\n    -m:\n        set the entry_point with format like `package.model:function`\n    -o:\n        set the output file path, you can set it some other paths like `/home/centos/example.abc` and run with `python3 /home/centos/example.abc`\n    no more new args.\n\n## 3. Package your code with requirements (bottle).\n\n3.1 The package `example` and the code of `__main__.py`\n\n        \u2514\u2500\u2500 example\n            \u251c\u2500\u2500 __init__.py\n            \u2514\u2500\u2500 __main__.py\n\n```python\ndef main():\n    import bottle\n    print(bottle.__version__)\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\n3.2 build the `example.pyz` with requirements installed\n\n> python3 -m zipapps -c -a example -o example.pyz -m example.__main__:main bottle\n\n3.3 Run with `python3 example.pyz` or `./example.pyz`\n\nOutput\n\n    0.12.19\n\nDetails:\n\n    bottle:\n        all the unhandled args (like `bottle`) will be used to `pip install`, so you can write `bottle` in requirements.txt and use like `-r requirements.txt`\n\n**WARNING**: if the requirements have `.pyd/.so` files, you should unzip them while running, and the pure python libs like `bottle` or `requests`  no need to unzip anything. Read the 4th paragraph for more info.\n\n## 4. Package your code with the requirements which includes `.pyd/.so` files.\n\n4.1 The package `example` and the code of `__main__.py`\n\n    \u2514\u2500\u2500 example\n        \u251c\u2500\u2500 __init__.py\n        \u2514\u2500\u2500 __main__.py\n\n```python\ndef main():\n    import psutil\n    print(psutil.__version__)\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\n4.2 build the `example.pyz` with requirements installed\n\n> python3 -m zipapps -c -a example -o example.pyz -m example.__main__:main -u AUTO -up TEMP/cache psutil\n\n4.3 Run with `python3 example.pyz` or `./example.pyz`\n\nOutput\n\n    5.8.0\n\nDetails:\n\n    -u:\n        means the file or folder names you want to unzip while running. Here is the `AUTO`, will unzip the psutil package because of its .pyd or .so files included.\n    -up:\n        the unzip path of cache folder. $TEMP/$HOME/$SELF/$PID/$CWD are the built-in runtime args, but for the stable usage you can ignore this arg then use `./zipapps_cache/example`. The cache will be refreshed while you rebuild this pyz.\n\nWARNING: unzip path can be overwrited by `export ZIPAPPS_CACHE=./xxx` or `export UNZIP_PATH=./xxx` while running.\n\n## 5. Package the requirements like a virtual environment without entry_point.\n\n5.1 Code of `script.py`\n\n```python\nimport bottle, requests\nprint(bottle.__version__, requests.__version__)\n```\n\n5.2 build the `venv.pyz` \n\n> python3 -m zipapps -c -o venv.pyz -p /usr/bin/python3 bottle requests\n\n5.3 Some use cases\n\n5.3.1 use the `venv.pyz` like a middleware\n\n> python3 venv.pyz script.py\n\n5.3.2 use the `venv.pyz` like the interpreter\n\n> ./venv.pyz script.py\n\neven like is also valid\n\n> `python3 venv.pyz -c \"import bottle,requests;print(bottle.__version__, requests.__version__)\"`\n\n5.3.3 use the `bottle` lib of `venv.pyz` in your normal code\n\n```python\nimport sys\nsys.path.append('path_to_venv/venv.pyz')\nimport bottle\n\nprint(bottle.__file__)\n```\n\n5.3.3 use the `pstuil` lib of `venv.pyz` in other normal code\n\n> python3 -m zipapps -c -o venv.pyz psutil\n\n```python\nimport sys\nsys.path.append('path_to_venv/psutil_venv.pyz')\n# need to activate the unzip action, there are 2 ways for the `.so/.pyd` libs\n# 1. use the default activate name\nimport activate_zipapps\n# 2. use a distinct lib name with file name for another venv file\nsys.path.append('path_to_venv/lxml_venv.pyz')\nimport ensure_lxml_venv\n# 2.1 or the old name\n# import ensure_zipapps_lxml_venv\n\n\nimport psutil\nimport lxml\n\nprint(psutil.__file__)\nprint(lxml.__file__)\n```\n\nOutput\n\n    0.12.19 2.25.1\n\nDetails:\n\n    No `-m` arg here, then the pyz file will do like an interpreter which contains the installed requirements.\n    \n    So you can use it like this:\n    > python3 venv.pyz\n    >>> import bottle\n    >>> bottle.__file__\n\n## 6. Using multiple venv pyz files for your pyz model.\n\n6.1 Here is `script.py` again\n\n```python\nimport bottle, requests\nprint(bottle.__version__, requests.__version__)\n```\n\n6.2 Build the `script.pyz`\n\n> python3 -m zipapps -c -o script.pyz -a script.py -m script requests\n\n6.3 Build the `requests.pyz` and `bottle.pyz` respectively\n\n> python3 -m zipapps -c -o requests.pyz requests\n> \n> python3 -m zipapps -c -o bottle.pyz bottle\n\n6.4 And now run the `script.pyz` with two requirements\n\n> python3 script.pyz --zipapps=bottle.pyz,requests.pyz\n\nOutput\n\n    0.12.19 2.25.1\n\nDetails:\n\n    --zipapps:\n        This arg will help you run some zipapp with given venv.pyz files, the paths is separated by commas.\n\n## 7. Package your code with lazy install mode, for a attempt of cross-platform.\n\n7.1 Here is `script.py` again\n\n```python\nimport six\nprint(six.__file__)\n```\n\n7.2 Build the `script.pyz`, this is very fast without downloading and installing 3rd packages.\n\n> python3 -m zipapps -c -o script.pyz -a script.py -m script -d six\n\n7.3 Run this `.pyz` file, and the requirements will be installed while first running.\n\n> python3 script.pyz\n\nOutput\n\n    Looking in indexes: https://pypi.xxx.com/simple/\n    Collecting six\n    Using cached https://xxx/packages/ee/ff/xxxx/six-1.15.0-py2.py3-none-any.whl (10 kB)\n    Installing collected packages: six\n    Successfully installed six-1.15.0\n    /tmp/zipapps_cache/script/_zipapps_lazy_pip/3.8/Linux/six.py\n\nDetails:\n\n    -d:\n        Lazy install mode is useful for distributing your cross-platform apps.\n\n</details>\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Package your python code into one zip file, even a virtual environment.",
    "version": "2024.8.7",
    "project_urls": {
        "Home": "https://github.com/ClericPy/zipapps"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b0b2ec467bb62be00d7d9ac6994044138bbd2aefb18f84a6ada90840920affad",
                "md5": "1f9406cc5ea18b5ac8e6c191a42fd00c",
                "sha256": "81996c5399ed0ffe97cd69dbb200eaf3710a4e878977961cd06148a688d74ff1"
            },
            "downloads": -1,
            "filename": "zipapps-2024.8.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1f9406cc5ea18b5ac8e6c191a42fd00c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 31081,
            "upload_time": "2024-08-07T15:26:50",
            "upload_time_iso_8601": "2024-08-07T15:26:50.041159Z",
            "url": "https://files.pythonhosted.org/packages/b0/b2/ec467bb62be00d7d9ac6994044138bbd2aefb18f84a6ada90840920affad/zipapps-2024.8.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "55f8c9c91f79479727f93fb8b8c1b77960fd4d3b1cd4590a775e53bbb57783ca",
                "md5": "95d0ccb0756ab19c85739715f8e98eff",
                "sha256": "5d92e9c9187bf79371519fb5afdecd3d7b2385c9a2f0d46f98ba8ed85063e15a"
            },
            "downloads": -1,
            "filename": "zipapps-2024.8.7.tar.gz",
            "has_sig": false,
            "md5_digest": "95d0ccb0756ab19c85739715f8e98eff",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 607137,
            "upload_time": "2024-08-07T15:26:54",
            "upload_time_iso_8601": "2024-08-07T15:26:54.766953Z",
            "url": "https://files.pythonhosted.org/packages/55/f8/c9c91f79479727f93fb8b8c1b77960fd4d3b1cd4590a775e53bbb57783ca/zipapps-2024.8.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-07 15:26:54",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ClericPy",
    "github_project": "zipapps",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "zipapps"
}
        
Elapsed time: 1.18510s