Skip to content

Commit

Permalink
add arg --ensure-pip
Browse files Browse the repository at this point in the history
  • Loading branch information
ClericPy committed Apr 29, 2021
1 parent daa1867 commit 88d4243
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 20 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ Package your python code (with requirements) into a standalone zip file.

Inspired by [shiv](https://github.com/linkedin/shiv) but unlike `shiv`

1. zipapps may not unzip cache when without any C language-based library or dynamic modules(`.so/.pyd`), such as `requests`, `bottle`, or your own pure python code.
2. cache path to unzip is `./zipapps_cache` by default, not the `HOME` path.
3. the cache folders will be reused for the same app name, not like shiv to create many new versions and use much disk space.
4. you can install requirements with `pip` while first running(not packaging) by lazy install mode, for cross-platform publishing and reducing your `.pyz` file size.
5. combine multiple `venv.pyz` files for your code flexibly.
1. `zipapps` may not create the cache folder while your package has no C language-based libraries or dynamic modules(`.so/.pyd`), such as `requests`, `bottle` or other pure python codes.
2. The default cache path is `./zipapps_cache`, but not the `HOME` path.
3. The cache folders will be reused for the `same app name`, not to create many new versions and use much disk space.
4. You can install requirements with `pip` while first running(not packaging) by `lazy install` mode, for cross-platform publishing and reducing your `.pyz` file size.
5. Using multiple `venv.pyz` files together.

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

# What is the `.pyz`?

Expand Down Expand Up @@ -397,7 +399,9 @@ Details:
1. Default `--zipapps` arg if it is not given while running. Support TEMP/HOME/SELF prefix.
16. `--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.
17. all the other (or `unknown`) args will be used by "pip install"
17. `--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]
18. 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`
Expand Down Expand Up @@ -440,5 +444,3 @@ Details:
1. `import sys;sys.path.insert(0, 'app.pyz')` (without .so/.pyd)
2. `python3 app.pyz script.py`
7. Other usages need to be found, and enjoy yourself.

# [Changelog.md](https://github.com/ClericPy/zipapps/blob/master/changelog.md)
Binary file modified args.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions args.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

# Changelogs

- 2021.04.29
- add arg `--ensure-pip` for embed-python(windows) or other python versions which have no `pip` installed but `lazy-install` mode is enabled.
- 2021.04.24
- remove conflict command args with `pip`
- remove `--compile` arg, it will only work for `pip`
Expand Down
11 changes: 10 additions & 1 deletion zipapps/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ def main():
action='store_true',
dest='lazy_install',
help='Install packages with pip while running, which means '
'requirements will not be install into pyz file. Default unzip path will be changed to `SELF/zipapps_cache`')
'requirements will not be install into pyz file. Default unzip path will be changed to `SELF/zipapps_cache`'
)
parser.add_argument(
'-pva',
'--python-version-accuracy',
Expand All @@ -185,6 +186,13 @@ def main():
dest='activate',
help='Activate the given paths of zipapps app, '
'only activate them but not run them, separated by commas.')
parser.add_argument(
'--ensure-pip',
action='store_true',
dest='ensure_pip',
help='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]')
if len(sys.argv) == 1:
return parser.print_help()
args, pip_args = parser.parse_known_args()
Expand Down Expand Up @@ -212,6 +220,7 @@ def main():
lazy_install=args.lazy_install,
sys_paths=args.sys_paths,
python_version_slice=int(args.python_version_slice),
ensure_pip=args.ensure_pip,
)


Expand Down
31 changes: 21 additions & 10 deletions zipapps/ensure_zipapps_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,29 @@ def prepare_path():
_pip_target.mkdir(parents=True, exist_ok=True)
try:
import pip
shell_args = [
sys.executable, '-m', 'pip', 'install', '--target',
lazy_pip_dir_str
] + pip_args
import subprocess
with subprocess.Popen(shell_args,
cwd=_cache_folder_path_str,
stdout=sys.stderr) as proc:
proc.wait()
except ImportError:
# try installing pip
cwd = os.getcwd()
os.chdir(_cache_folder_path_str)
import ensurepip
ensurepip.bootstrap()
import subprocess
shell_args = [
sys.executable, '-m', 'pip', 'install', '--target',
lazy_pip_dir_str
] + pip_args
with subprocess.Popen(shell_args,
cwd=_cache_folder_path_str,
stdout=sys.stderr) as proc:
proc.wait()
assert ensurepip._bootstrap(root=lazy_pip_dir_str) == 0
for _path in _pip_target.glob('**/pip/'):
if _path.is_dir():
sys.path.append(str(_path.parent.absolute()))
break
import pip
args = ['install', '-t', lazy_pip_dir_str] + pip_args
pip.main(args)
os.chdir(cwd)
# avoid duplicated installation
(_pip_target / pip_args_md5).touch()
sep = ';' if sys.platform == 'win32' else ':'
Expand Down
14 changes: 13 additions & 1 deletion zipapps/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from pkgutil import get_data
from zipfile import BadZipFile, ZipFile

__version__ = '2021.04.27'
__version__ = '2021.04.29'


class ZipApp(object):
Expand Down Expand Up @@ -47,6 +47,7 @@ def __init__(
lazy_install: bool = False,
sys_paths: str = '',
python_version_slice: int = 2,
ensure_pip: bool = False,
):
"""Zip your code.
Expand Down Expand Up @@ -86,6 +87,8 @@ def __init__(
:type sys_paths: str, optional
:param python_version_slice: Only work for lazy-install mode, then `pip` target folders differ according to sys.version_info[:_slice], defaults to 2, which means 3.8.3 equals to 3.8.4 for same version accuracy 3.8, defaults to 2
:type python_version_slice: int, optional
:param ensure_pip: 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.
:type includes: bool, optional
"""
self.includes = includes
self.cache_path = cache_path
Expand All @@ -106,6 +109,7 @@ def __init__(
self.lazy_install = lazy_install
self.sys_paths = sys_paths
self.python_version_slice = python_version_slice
self.ensure_pip = ensure_pip

self._tmp_dir: tempfile.TemporaryDirectory = None
self._build_success = False
Expand Down Expand Up @@ -142,6 +146,13 @@ def ensure_args(self):
f'[INFO]: output path is `{self._output_path}`, you can reset it with the arg `output`.'
)

def prepare_ensure_pip(self):
if self.ensure_pip:
import ensurepip
ensurepip_dir_path = Path(ensurepip.__file__).parent
shutil.copytree(str(ensurepip_dir_path.absolute()),
self._cache_path / ensurepip_dir_path.name)

def build(self):
self._log(
f'{"=" * 10} Start building `{self._output_path}` with zipapps version <{__version__}> {"=" * 10}'
Expand All @@ -150,6 +161,7 @@ def build(self):
if self.build_exists():
return self._output_path
self.prepare_includes()
self.prepare_ensure_pip()
self.prepare_pip()
self.prepare_entry_point()
if self.build_id_name:
Expand Down

0 comments on commit 88d4243

Please sign in to comment.