eGenix PyRun™ is our one-file, portable, no-install version of
Python, making the distribution of a Python interpreter to run based
scripts and applications to Unix based systems as simple as copying a
single file.

●Compatible with setuptools,
easy_install, pip: Great care was taken to make sure that
PyRun can be used with setuptools et al.[1]

●Perfect virtualenv
replacement: PyRun provides an even better level of isolation
from the system installed Python version. Instead of using symlinks and
other tricks to create a virtual Python environments, PyRun comes with
a complete Python runtime and thus doesn't need to play any tricks.

●install-pyrun script:
Using the bash script install-pyrun,
we make the whole installation process even easier. It automatically
downloads and installs the right version for your platform and also
take care of adding setuptools and pip to the PyRun installation.

●Install a complete Python
runtime including dependencies in one go: using our install-pyrun
installation bash script, you can install PyRun as well as all
dependencies using a single install-pyrun -r
requirements.txt run.

●Open Source: PyRun is
licensed under the eGenix Public License. This Python-style makes it
possible to integrate PyRun into other open-source or commercial
products

●Commerical Support:
eGenix provides commercial support for PyRun, in case you need custom
builds, help with the integration or need problem solving support.

eGenix PyRun integrates a few standard Python extension modules, which
rely on system provided third-party libraries to be available on the
build system as development versions, and on the target system as
binary versions.

To simplify the installation of eGenix PyRun and make it as easy to use
as virtualenv, we've
created a shell script called install-pyrun that you can download
from our server. It is also distributed in the source archives
of PyRun in the PyRun/ folder.

After download of the script, you have to make it executable and place
it on your path:

With the script, you can automate the whole installation process
easily. In order to install the set of eGenix PyRun (together with the
Python include files and some extra C extensions from the stdlib that
are not compiled into PyRun), setuptools and pip to a new directory
targetdir, just run the following command:

./install-pyrun targetdir

This will then download a suitable eGenix PyRun binary distribution for
your platform, install setuptools and pip:

$ install-pyrun targetdir

Installing eGenix PyRun ...

Installing local setuptools 15.2 ...

Installing local pip 1.5.6 ...

eGenix PyRun was installed in targetdir

To run eGenix PyRun, use targetdir/bin/pyrun

$ cd targetdir

$ bin/pyrun -c 'print "Hello World!"'

Hello World!

$ bin/pyrun

eGenix PyRun 2.7.8 (release 2.0.1, default, Aug 27 2014, 00:58:48)

[GCC 4.5.1 20101208 [gcc-4_5-branch revision 167585]]

Thank you for using eGenix PyRun. Type "help" or "license" for details.

>>>

The script comes with a set of options to customize the version,
platform, Unicode variant and also allows disabling installation of
setuptools and pip as well as permit installation from a local PyRun
archive.

Simply run the script with option -h to see all options:

$ install-pyrun -h

Install eGenix PyRun in a given target directory.

USAGE:

install-pyrun [options] targetdir

OPTIONS:

-m or --minimal

install eGenix PyRun only (no setuptools and pip)

-l of --log

log installation to targetdir/pyrun-installation.log

-q or --quiet

quiet installation

-r or --requirements

have pip install the given requirements (only works

if pip is installed as part of the pyrun installation)

--python=2.7

install PyRun for Python version 2.6, 2.7 (default), 3.4

--python-unicode=ucs2

install PyRun for Python Unicode version

ucs2 (default for Python 2) or ucs4 (default for Python 3)

--pyrun=2.1.0

install PyRun version 2.1.0 (default)

--platform=linux-i686

install PyRun for the given platform; this is usually

auto-detected

--platform-list

list available platform strings

--pyrun-distribution=pyrun.tgz

use the given PyRun distribution file; this overrides

all other distribution selection parameters

--pyrun-executable=pyrun

symlink to and use an alternative name for the PyRun

executable

--setuptools-distribution=setuptools.tgz

use the given setuptools distribution file instead of

downloading it from PyPI

--setuptools-version=15.2

install the setuptools 15.2 (default); use

--setuptools-version=latest to automatically find the

latest version on PyPI

--distribute-distribution=distribute.tgz

alias for --setuptools-distribution

--pip-distribution=pip.tgz

use the given pip distribution file instead of

downloading it from PyPI

--pip-version=1.5.6

install the pip 1.5.6 (default); use --pip-version=latest

to automatically find the latest version on PyPI

--help

show this text

--version

show the script version

--copyright

show copyright

--debug

enable debug output

--disable-certificate-checks

disable certificate checks when downloading packages;

this should normally not be needed

Without options, the script installs eGenix PyRun, setuptools and pip

in targetdir. If no local versions of setuptools or pip are found, the

tools are downloaded from pypi.python.org.

The exact versions of pyrun, pip and setuptools listed in the above
output may be different in case you downloaded a more recent version of
the script.

install-pyrun will use
curl as default downloader, and fallback to
wget, if curl is not available. The script
defaults to operating the downloaders in secure mode, i.e. all links
are HTTPS links and all certificates are verified before proceeding
with the download.

Both the pypi.python.org and our downloads.egenix.com servers use HTTPS
for enhanced security.

Simply download a suitable binary distribution for the version of
Python and platform you need and extract it to a base directory where
you'd like PyRun to live. Then use the eGenix PyRun executable like
you'd use a regular Python interpreter, e.g.

./bin/pyrun2.7 myscript.py

You can also put pyrun into the shebang of the script, e.g.

#!/usr/bin/env pyrun2.7
# Hello World Demo
print "Hello World!"

Please note that the binary distributions contain more than just the
PyRun executable. They also come with a few extra standard library
extensions which are normally not part of PyRun and the include files
needed to compile Python extensions for use with PyRun.

If you are just looking for the plain single-file PyRun executable,
only extract the file bin/pyrunX.X (with X.X being the underlying
Python version, e.g. 2.7) from the binary distributions.

If you want to install other libraries or packages for use in eGenix
PyRun, you need to pay a little more attention to where you copy the
executable. eGenix PyRun assumes the following directory layout
relative to the executable (with X.X being the underlying
Python version, e.g. 2.7):

●bin/pyrunX.X

●lib/pythonX.X

●include/pythonX.X (Python 2)
or include/pythonX.Xm
(Python 3)

The lib/pythonX.X
directory is used as location of the Python libraries and
automatically put on sys.path in case it is available. Optional
packages installed through distutils or setuptools will go into the
corresponding lib/pythonX.X/site-packages/
directory.

The lib/pythonX.X
directory may also contain Python standard library extension modules in
the lib-dynload/
sub-directory which are not integrated into the eGenix PyRun
executable. The prebuilt binary distributions come with a set of
such extensions.

The include/pythonX.Xdirectory is
only needed in case you want to compile Python C extensions. It is
available as part of the prebuilt binary distributions we make
available. For Python 3, the include directory has the ABI flags
appended. For Python 3.4, this is include/python3.4m for most
Python installations.

Please note that while eGenix PyRun itself is fully
relocatable after installation due to the relative search
path, the tools setuptools and pip are not. They
hard-code the paths into their scripts, so you can not relocate a
PyRun installation, after these tools have been installed.

To facilitate shipping custom external libraries with PyRun, newer
versions of PyRun (2.1 and later) add an rpath setting to
the binary which results in the dynamic linker on compatible systems to
first look in these directories for shared libraries such as OpenSSL,
SQlite, ZLib or BZip2 libraries. or SQLite.

The rpath setting defines a dynamic library search path which is used
if no LD_LIBRARY_PATH OS environment variable is
set.

If you would rather install to a different directory, you can add the
make parameter PREFIX=/path/to/pyrun/, This will cause make
to install eGenix PyRun in /path/to/pyrun/.

If you want to build against a specific Python version, you can specify
the version using the make parameter PYTHONFULLVERSION=2.7.5. Please have a look
at the PyRun/Makefile for more
ways of customizing the setup.

For future versions of eGenix PyRun, we plan to make the setup
customizable via a top-level setup.py file so you can use
Python to trigger the build, customize the included standard lib
extension modules and installation.

eGenix PyRun uses the standard Python freeze tool, which you can find
the Tools/freeze/
directory of the Python source code distribution to combine the Python
interpreter with a large subset of the Python standard library into a
single-file Python runtime.

We have applied a few customizations to the freeze tool and ship
separate versions for Python 2 and Python 3 with the source
distribution of eGenix PyRun.

In order to use freeze.py for creating PyRun, we had to implement these
steps:

● we created a freeze.py template (PyRun/Runtime/pyrun_template.py)
which provides a mostly compatible command line interface to the
standard Python interpreter and references the standard library modules
that we wanted to include in PyRun,

● we extract the Python configuration
information from the Python Makefile and configure files and put this
information into a static configuration template (PyRun/Runtime/pyrun_config_template.py),
which is then used by sysconfig.py to load the configuration,

● we extract the Python grammar files the
Python stdlib, so that the lib2to3 package can work without having the
files loaded from the file system and put this information into a
static configuration template (PyRun/Runtime/pyrun_grammar_template.py),
which is then used by lib2to3 to load the configuration,

● we created a script (PyRun/makepyrun.py) which
creates all the necessary pyrun*.py files from the templates,

● we added patches to Python (PyRun/Runtime/Python-*.patch)
and the Modules/Setup files (PyRun/Runtime/Setup.PyRun-*)
to be able to statically link in extension modules that would normally
be built as shared modules and to provide a pure-Python implementation
of the Python command line interface.

The PyRun/Makefile
extracts the Python source code, applies the patches and adds the Modules/Setup file.

It then creates the pyrunX.X.py freeze.py
template, the pyrun_config.py module and
runs PyRun/Runtime/freeze/freeze.py
on the generated pyrunX.X.py file.

freeze.py then generates the frozen module versions and a Makefile in
PyRun/Runtime/Makefile
which can then be used to build the pyrunX.X executable.

The PyRun/Makefile also
takes care of installing the executable together with the include files
and optional shared modules built during the process; as well as
packaging the builds into binary .tar.gz files, which can simply be
extracted anywhere in the file system to "install" eGenix PyRun.

If you want to further reduce the PyRun file size, you can remove
additional modules/packages from the frozen binary by editing the PyRun/Runtime/makepyrun.py
file and adding the modules/packages to the remove lists.

In some cases, this may not be enough to completely remove the
modules/packages, e.g. if you still have other modules in PyRun which
reference the removed modules/packages, freeze.py is going to re-add
them in the module search process.

To overcome this limitation, you will have to additionally add the
modules/packages to the PyRun/MakefileEXCLUDESvariable.

In a future version of eGenix PyRun, we're going to simplify this
process so that you can pass the modules to exclude as parameter to the
build script.

This is a list of changes we have applied compared to standard Python.
Unlike the compatibility fixes listed in the next sections, these are
features that are not necessary to get eGenix PyRun to work, but ones
that we think are slightly more useful than the standard Python
choices.

In Python 3.4, the Python I/O encoding is determined by looking at the
locale of the process. Depending on the used system, this can be UTF-8,
ASCII or some other encoding.

Since we think it's better to either correctly set the encoding via an
environment variable such as PYTHONIOENCODING and not guess, we chose
to define a default for the PYTHONIOENCODING which is used, in case
this environment variable is not set.

The default for PYTHONIOENCODING in eGenix PyRun 3.4 is
"utf-8:surrogateescape". This allows pyrun to work in most situations
without failing prints or weird encoding exceptions.

If you do have a different setup or would like exceptions for non-UTF-8
data to be raised, you can set the PYTHONIOENCODING environment
variable to override this default.

It is even possible to have eGenix PyRun revert back to the locale
scanning behavior by setting the PYTHONIOENCODING variable to "" (empty
string).

Since PyRun is normally used in isolated environments in which per-user
installations are not really wanted, we have disabled the flag ENABLE_USER_SITE in site.py of the standard
library to disable setup of the user-site configurations.

This means that PyRun will not automatically search these user
site-packages directories and also not install into them. It also means
that sys.path search run faster and startup time is a little better as
a result.

Simulating user installations

Note that PyRun's site-packages directory is always set up relative to
the location of the PyRun binary, so using user site configurations
should not be needed.

If you want to simulate a user site installation with PyRun, you can
create a local installation of PyRun based on a system-wide one by
either copying the binary or simply creating a symbolic link in a
user's subdirectory.

The site.py setup
module checks for the availability of a lib/site-python directory and
adds this to sys.pathif found. Since this directory is
hardly ever used and very uncommon for the isolated run-time
environments for which PyRun is intended, we have disabled this
addition.

Python 2.7.9 and 3.4+ introduced many changes to the SSL support of
Python. The Python 3.4 ssl module was backported to Python 2.7 in 2.7.9
and the default HTTPS certificate verification checks enabled per
default (see PEP 476)

Even though this results in making Python 2.7 more secure, it also
means that that Python 2.7 now needs access to a reliable and
up-to-date trust store which has the trusted CA root certificates.
HTTPS requests to websites or servers which don't provide certificates
listed in those CA root certificates will be rejected, unless the
application code explicitly permits such connections.

This will in many cases result in Python not accepting CA Cert
certificates or self-signed certificates anymore, which are often used
in test setups or by embedded systems.

eGenix PyRun provides a way to disable these checks using an
environment variable PYRUN_HTTPSVERIFY:

PYRUN_HTTPSVERIFY

When set to 0, PyRun will use the unverified SSL context for HTTPS
connections per default, just like Python 2.7.8 and earlier did.

Setting this variable to 1 will force the default to also verify the
HTTPS certificates.

In standard Python 2, the attribute is always set to "<frozen>".
In standard Python 3, the attribute does not exist at all.

This poses many problems to software relying on this attribute for
reporting and debugging purposes (e.g. to show the location of an
error) or produce coverage reports.

Since it's impossible to fix all this third party software, we chose to
alwas add the attribute to frozen modules. The attribute is set to
"<pyrun>/package/module.py"
for all modules frozen into pyrun. This allows most uses of the
attribute to work without problems.

Some modules also use this attribute to locate external resources
relative to the module location. Since the attribute does not point to
an existing path, this will fail, so special work-arounds have to put
in place for such software.

On the positive side, several such modules do take the situation into
account that the path does not exist and fall back to other solutions.

The lib2to3 package comes with its own pgen2 parser. This parser uses a
special set of grammar files for Python's grammar which are embedded
into the package.

Since we cannot ship those files in the file system, we chose to stored
the grammar pickles in a pyrun_grammar.py helper
module and patched the package to use these pickles instead.

This allows lib2to3 to work without having to read the grammar files
and makes on-the-fly conversions during installation possible. An
important example of a package which uses this technique for Python 3
support is setuptools.

The lib2to3 package scans its own fixes/ directory for available fix
modules. In a frozen package this doesn't work, so we preprocessed the
list, put it into the pyrun_config.py module and
patched lib2to3 to load it from there.

While porting eGenix PyRun to Python 3.4 we found a couple of bugs in
stdlib modules which we patch in pyrun for the supported Python
versions and also reported upstream. Please see the change log on the
eGenix
product web page for details.

In order to have the standard library extensions linked into the pyrun
binary instead of having them built as separate module, eGenix PyRun
defines additional entries for them in the Modules/Setup file.

Several modules are documented there, but not all of them. We extracted
the relevant information from the Python setup.py file and added it
manually to the Modules/Setup file for each
supported Python version.

Since the Modules/Setup
process is not nearly as flexible as the setup.py process,
configuration of the modules is sometimes very complicated. For this
reason we have punted on a few packages such as the ctypes package and
instead added them to the distributed binaries as separately
installable dynamic shared modules.

Note that it is possible to customize these Module/Setup files further
in case you would like to add other third party extensions to the pyrun
binary.

We have deliberately excluded a number of standard library modules that
are either to complicated to build, have license issues or are not
needed often enough in our use cases to warrant including in eGenix
PyRun:

● *dbm modules

● crypt

● readline

● parser

● tkinter

● _multiprocessing

● all test packages and sub-packages

● ctypes

● nis

● audio modules

● _decimal (in Python 3)

The modules are still built (if the needed development files are found
on the build system) and packaged in the eGenix PyRun distribution
files, so you can use them, if you need to.

However, they are not statically linked into the PyRun executable, so
when moving this file around, you have to make sure that the relative
directory structure expected by PyRun (see 1.3.4eGenix PyRun Directory
Structure) makes it possible to find those shared modules.

Some standard library modules/packages come with non-Python resource
files such as binary .exe stubs or data files. Since freeze.py will only find
Python modules, these files are not included in the frozen PyRun
executable and since the frozen modules/packages don't live in the file
system, access to such resource files is not possible via the
module/package path.

Examples of such modules/packages:

●idellib

● distutils' bdist_wininst (the rest of distutils works
fine)

●pkgutilon frozen packages (it works on frozen
modules in Python 2.7)

● several test modules/packages (not
included anyway)

For the lib2to3 package, which also needs external files, we have
patched the package and included the necessary grammar files in the
pyrunbinary, since it is used by several
Python packages during installation on Python 3.

The pkgutilmodule which is needed to implement
the -m option in Python only has limited support
for frozen modules in Python 2.7 and 3.4. It has no support for frozen
packages. As a result, running pyrun2.7 -m
timeit works, but e.g. pyrun2.7 -m
lib2to3 --help doesn't.

Running the Python test suite shows some strange issues which we have
not yet tracked down:

● Some test modules hang when run with
regrtest.py, e.g. test_docxmlrpc

● Test modules cause strange errors
(mostly encoding errors) when run with regrtest.py. Running the test modules
directly doesn't show these errors. Some preliminary investigation
suggests that these issues could be caused by regrtest.py modifying the module __path__ entries.

Because eGenix PyRun has to emulate the command line options in Python,
it is difficult to emulate some Python command line option which take
effect in the very early stages of the interpreter startup phase.

For some options like e.g. -d (debug level) and -O (optimization
level), we have added helpers/patches to Python to make it possible
adjusting them from Python.

Fortunately, most of the more exotic options are not used in production
runtime environments for which eGenix PyRun is designed.

Here's a short session installing setuptools, pip and our
egenix-mx-base package in an eGenix PyRun installation.

Please note that installing eGenix PyRun is much easier using the
install-pyrun bash script we provide, which
automates the following steps. See 1.3.2Quick install using
install-pyrun for instructions on how to obtain and use this script.

Now we have a ready to use Python runtime in tmp/, using the default
eGenix PyRun directory layout, including some optional extra shared
libraries and the include files needed for compiling Python C
extensions.

eGenix PyRun supports the Python -v and -d command line switches to
give you extra information about how processing is done. Both switches
enable additional output from eGenix PyRun as well as Python itself,
since the command line switches are passed to Python.

Please note however that these switches are enabled in Python by the
eGenix PyRun command line emulation which is written in Python. As a
result, they are not in effect in the early setup stages of PyRun
startup and don't include the early startup time information available
in Python itself.

If you need to debug imports and get more information about how eGenix
PyRun executes the scripts, the -v command line switch is useful. It
tells PyRun to output additional useful information to stderr and also
enable the Python verbose flag which results in Python writing import
searches and GC cleanup details to stderr.

This software is covered by the eGenix.com Public License
Agreement, which is included in the following section.
The text of the license is also included as file "LICENSE" in the
package's main directory.

Since eGenix PyRun also pulls in Python, the respective Python license
also applies to the resulting pyrun binary. The Python license is
included as file "LICENSE.Python" in the package's main directory as
well as the eGenix
Third-Party License document.

In simple words, you are free to use the software without paying fees
or royalties as long as you give proper attribution and keep the
license documents together with the software. Please see the license
document for details and consult a lawyer if you have legal questions.

This "License Agreement" is between eGenix.com Software, Skills and
Services GmbH ("eGenix.com"), having an office at Pastor-Loeh-Str. 48,
D-40764 Langenfeld, Germany, and the Individual or Organization
("Licensee") accessing and otherwise using this software in source or
binary form and its associated documentation ("the Software").

2. License

Subject to the terms and conditions of this eGenix.com Public License
Agreement, eGenix.com hereby grants Licensee a non-exclusive,
royalty-free, world-wide license to reproduce, analyze, test, perform
and/or display publicly, prepare derivative works, distribute, and
otherwise use the Software alone or in any derivative version,
provided, however, that the eGenix.com Public License Agreement is
retained in the Software, or in any derivative version of the Software
prepared by Licensee.

3. NO WARRANTY

eGenix.com is making the Software available to Licensee on an "AS IS"
basis. SUBJECT TO ANY STATUTORY WARRANTIES WHICH CAN NOT BE
EXCLUDED, EGENIX.COM MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, EGENIX.COM MAKES
NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR
FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL
NOT INFRINGE ANY THIRD PARTY RIGHTS.

4. LIMITATION OF LIABILITY

EGENIX.COM SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
LOSS) AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR
ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.

SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF
INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE EXCLUSION OR
LIMITATION MAY NOT APPLY TO LICENSEE.

5. Termination

This License Agreement will automatically terminate upon a material
breach of its terms and conditions.

6. Third Party Rights

Any software or documentation in source or binary form provided along
with the Software that is associated with a separate license agreement
is licensed to Licensee under the terms of that license agreement. This
License Agreement does not apply to those portions of the Software.
Copies of the third party licenses are included in the Software
Distribution.

7. General

Nothing in this License Agreement affects any statutory rights of
consumers that cannot be waived or limited by contract.

Nothing in this License Agreement shall be deemed to create any
relationship of agency, partnership, or joint venture between
eGenix.com and Licensee.

If any provision of this License Agreement shall be unlawful, void, or
for any reason unenforceable, such provision shall be modified to the
extent necessary to render it enforceable without losing its intent,
or, if no such modification is possible, be severed from this License
Agreement and shall not affect the validity and enforceability of the
remaining provisions of this License Agreement.

This License Agreement shall be governed by and interpreted in all
respects by the law of Germany, excluding conflict of law provisions.
It shall not be governed by the United Nations Convention on Contracts
for International Sale of Goods.

This License Agreement does not grant permission to use eGenix.com
trademarks or trade names in a trademark sense to endorse or promote
products or services of Licensee, or any third party.

The controlling language of this License Agreement is English. If
Licensee has received a translation into another language, it has been
provided for Licensee's convenience only.

8. Agreement

By downloading, copying, installing or otherwise using the Software,
Licensee agrees to be bound by the terms and conditions of this License
Agreement.

For question regarding this License Agreement, please write to:

eGenix.com Software, Skills and Services GmbH

Pastor-Loeh-Str. 48

D-40764 Langenfeld

Germany

[1] Please note
that setuptools and pip are not designed to be relocatable.