Skip to content

Instantly share code, notes, and snippets.

@miku
Last active March 22, 2023 12:38
Show Gist options
  • Save miku/e0a3d4abb2ba7dbb9ca5f11369fc64f4 to your computer and use it in GitHub Desktop.
Save miku/e0a3d4abb2ba7dbb9ca5f11369fc64f4 to your computer and use it in GitHub Desktop.
Minimal zipapp-ish thingy using shiv (https://github.com/linkedin/shiv)
app.zip
build/lib/hello.py
zhello.egg-info

Minimal zipapp-ish thingy using shiv (https://github.com/linkedin/shiv).

Cf. https://stackoverflow.com/questions/73040963/modulenotfound-exception-with-zipapp-and-compiled-c-code

Try it out

Note that shiv needs Python 3.6 or higher.

$ pip install shiv

Get this gist, build the zipapp:

$ git clone https://gist.github.com/e0a3d4abb2ba7dbb9ca5f11369fc64f4.git
$ cd e0a3d4abb2ba7dbb9ca5f11369fc64f4

Make sure you have cysystemd dependencies installed, e.g. libsystemd-dev.

$ make

Then run it:

$ ./app.zip
cysystemd.journal

Why does it work?

While the above application is a zipapp, it won't run out of the zip file (hence no limit of what can be imported). Shiv (and other tools in that space) transparently extract the zip file to a temporary folder and run code from there.

With shiv, you can set the temporary folder with SHIV_ROOT:

This should be populated with a full path, it overrides ~/.shiv as the default base dir for shiv’s extraction cache.

This is useful if you want to collect the contents of a zipapp to inspect them, or if you want to make a quick edit to a source file, but don’t want to taint the extraction cache.

e.g.

$ SHIV_ROOT=./cache ./app.zip
cysystemd.journal

$ tree cache/
cache/
└── app.zip_cdde0f2901e8f2cd2119aee9945b9e5dd0492f53a59d05143d4e41ab09005144
    └── site-packages
        ├── bin
        │   └── zhello
        ├── cysystemd
        │   ├── async_reader.py
        │   ├── _daemon.cpython-38-x86_64-linux-gnu.so
        │   ├── daemon.py
        │   ├── __init__.py
        │   ├── _journal.cpython-38-x86_64-linux-gnu.so
        │   ├── journal.py
        │   ├── __pycache__
        │   │   ├── __init__.cpython-38.pyc
        │   │   └── journal.cpython-38.pyc
        │   ├── py.typed
        │   └── reader.cpython-38-x86_64-linux-gnu.so
        ├── cysystemd-1.5.3.dist-info
        │   ├── INSTALLER
        │   ├── LICENSE
        │   ├── METADATA
        │   ├── RECORD
        │   ├── top_level.txt
        │   └── WHEEL
        ├── hello.py
        ├── __pycache__
        │   └── hello.cpython-38.pyc
        └── zhello-0.0.0.dist-info
            ├── direct_url.json
            ├── entry_points.txt
            ├── INSTALLER
            ├── METADATA
            ├── RECORD
            ├── REQUESTED
            ├── top_level.txt
            └── WHEEL

8 directories, 27 files

For reference, the contents of app.zip:

$ unzip -l app.zip
Archive:  app.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
      203  2022-07-19 20:24   site-packages/bin/zhello
        4  2022-07-19 20:24   site-packages/cysystemd-1.5.3.dist-info/INSTALLER
    11357  2022-07-19 20:24   site-packages/cysystemd-1.5.3.dist-info/LICENSE
     9956  2022-07-19 20:24   site-packages/cysystemd-1.5.3.dist-info/METADATA
     1404  2022-07-19 20:24   site-packages/cysystemd-1.5.3.dist-info/RECORD
      103  2022-07-19 20:24   site-packages/cysystemd-1.5.3.dist-info/WHEEL
       10  2022-07-19 20:24   site-packages/cysystemd-1.5.3.dist-info/top_level.txt
      467  2022-07-19 20:24   site-packages/cysystemd/__init__.py
   121760  2022-07-19 20:24   site-packages/cysystemd/_daemon.cpython-38-x86_64-linux-gnu.so
   345352  2022-07-19 20:24   site-packages/cysystemd/_journal.cpython-38-x86_64-linux-gnu.so
     6146  2022-07-19 20:24   site-packages/cysystemd/async_reader.py
     2661  2022-07-19 20:24   site-packages/cysystemd/daemon.py
     4880  2022-07-19 20:24   site-packages/cysystemd/journal.py
        0  2022-07-19 20:24   site-packages/cysystemd/py.typed
  2451824  2022-07-19 20:24   site-packages/cysystemd/reader.cpython-38-x86_64-linux-gnu.so
      110  2022-07-19 20:24   site-packages/hello.py
        4  2022-07-19 20:24   site-packages/zhello-0.0.0.dist-info/INSTALLER
      190  2022-07-19 20:24   site-packages/zhello-0.0.0.dist-info/METADATA
      833  2022-07-19 20:24   site-packages/zhello-0.0.0.dist-info/RECORD
        0  2022-07-19 20:24   site-packages/zhello-0.0.0.dist-info/REQUESTED
       92  2022-07-19 20:24   site-packages/zhello-0.0.0.dist-info/WHEEL
       86  2022-07-19 20:24   site-packages/zhello-0.0.0.dist-info/direct_url.json
       39  2022-07-19 20:24   site-packages/zhello-0.0.0.dist-info/entry_points.txt
        6  2022-07-19 20:24   site-packages/zhello-0.0.0.dist-info/top_level.txt
     2063  2022-07-19 20:24   _bootstrap/filelock.py
     8809  2022-07-19 20:24   _bootstrap/__init__.py
     2878  2022-07-19 20:24   _bootstrap/environment.py
     1762  2022-07-19 20:24   _bootstrap/interpreter.py
      353  2022-07-19 20:24   environment.json
       65  2022-07-19 20:24   __main__.py
---------                     -------
  2973417                     30 files
from cysystemd import journal
def main():
print(journal.__name__)
if __name__ == '__main__':
main()
SHELL := /bin/bash
app.zip:
shiv --entry-point hello:main --python "/usr/bin/env python3" --output-file app.zip .
.PHONY: clean
clean:
rm -rf app.zip build/ zhello.egg-info/ cache/
import setuptools
setuptools.setup(
name="zhello",
py_modules=["hello"],
python_requires=">=3.6",
entry_points={"console_scripts": [
"zhello=hello:main"
]},
install_requires=[
"cysystemd==1.5.3",
],
)
@samba2
Copy link

samba2 commented Jul 19, 2022

Wow🙏. Need to try this tomorrow. Many thanks👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment