Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/cli-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ include the minor version (e.g. ``… python3.6``) – use what fits your circum
On Windows, the Python launcher ``py`` knows how to handle shebangs using ``env``,
so it's overall the best choice if you target multiple platforms with a pure Python zipapp.

If you have ``coreutils`` with at least version 8.30 on your Linux system,
then you can use env shebangs *and* pass arguments to Python, like in this example:

.. code-block:: shell

shiv -p '/usr/bin/env -S python3 -I -S' …

The magic ingredient is the new ``-S`` (split) option, but as of 2020
you have to target very new stable releases like Debian Buster
or rolling distributions for it to actually work.
Check for the option by calling ``env --help``.

Comment on lines +38 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we omit this entry for this change? I appreciate that we want to educate users about what is possible with shebangs, but given that the tool in question (shiv) has no opinion about the shebang, I'd rather not introduce this concept in our documentation.

Also note that you can always fix the shebang during installation of a zipapp using this:

.. code-block:: shell
Expand Down
91 changes: 91 additions & 0 deletions docs/how-tos.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
**********************
How-Tos, Tips & Tricks
**********************

This chapter contains some practical examples of using ``shiv`` in the real world,
to give you a better idea how it can fit into your projects
and their deployment workflows.


Shipping Dependency Sets as a Single File
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about referring to these as "frozen environments" rather than "dependency sets". This is usually how we refer to them internally, but I want to know if it makes sense in the broader Python community.

=========================================

If you have a bunch of Python scripts that are all using the same set of base libraries,
you can distribute those dependencies in the form of a zipapp,
i.e. in a single executable file.
This way, you can have a project for the base libraries
and other projects for the scripts,
including scripts written by your end users.

The following example uses ``shiv`` itself for demonstration purposes,
you'd use a setuptools project defining the needed dependencies
when applying this ‘for real’.

So, to create your base library release artifact, call
``shiv`` like this in your project's workdir::

PROJECT=shiv
shiv -p '/usr/bin/python3.6 -IS' -o ~/bin/_lib-$PROJECT .

Note that we do not provide an entry point here, which means this zipapp
drops into the given Python interpreter and is thus usable *as* an
interpeter, but with the dependencies of the project added.

The ``-IS`` options in ``-p`` ensure this zipapp runs isolated (for increased security),
with neither the current working directory
nor the host's site packages in the Python path.
Comment on lines +34 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's omit this (and the flags) in the example, to not confuse users and discourage copy-pasted boilerplate.


.. tip::

Replace the ``.`` at the end of the ``shiv`` call
by a literal list of PyPI packages,
or load them from a requirements file (``-r lib-requirements.txt``),
and you don't need an extra project for getting your base set defined.
Comment on lines +38 to +43
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good tip, can you call out the . earlier than this tip as well? I can imagine someone reading this doc may gloss right over the . on line 28 and be confused when they see this tip, but if you call it out (after the note about not providing an entry point, maybe) the reader will have proper context. Which is also a good opportunity to let them know that any non-shiv arguments/flags get delegated to pip.


Now we can exploit this to write a script using the zipapp as its interpreter::

cat >script <<'.'
#! /usr/bin/env _lib-shiv
import sys
from pathlib import Path
import shiv

print('Imported shiv from',
Path(shiv.__file__).parent,
'\nPython path:',
'\n'.join(sys.path),
sep='\n')
.
chmod +x script
./script

Calling the script produces the following output::

Imported shiv from
/home/user/.shiv/_lib-shiv_8a…e9/site-packages/shiv

Python path:
/home/user/bin/_lib-shiv
/usr/lib/python36.zip
/usr/lib/python3.6
/usr/lib/python3.6
/usr/lib/python3.6/lib-dynload
/home/user/.shiv/_lib-shiv_8a…e9/site-packages

The underscore prefix in the zipapp name indicates this is not a command
humans would normally use – alternatively you can deploy into e.g.
``/usr/local/lib/python3.6/`` and then use an absolute path instead of
an ``env`` call in the script's shebang.
Comment on lines +75 to +78
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can omit this, don't want to overload the reader with info that's not critical.



External Resources
==================

Here are some links to related articles on the web.

* `Python Alternative to Docker`_ – Comparing shiv to Docker as the core tool of a deployment workflow, what are the differences between and advantages of both options.
* `Enabling Easy Zipapp Installs on Windows`_ – Describes the required steps to make zipapps really shine on Windows (i.e. make them work pretty much like on POSIX systems).


.. _`Python alternative to Docker`: https://www.mattlayman.com/blog/2019/python-alternative-docker/
.. _`Enabling Easy Zipapp Installs on Windows`: https://py-generic-project.readthedocs.io/en/latest/installing.html#enabling-easy-zipapp-installs-on-windows
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ Table of Contents
:maxdepth: 2

cli-reference
how-tos
history
api
django
Expand Down