Working with Python PEX Files

Suppose you have a package that imports a lot of weird modules and you’d like to share this package without forcing end users to install a bunch of stuff. You can bundle this into a PEX file and everyone will live happily ever after.

PEX Files

Well, it’s a carefully crafted zip file of egg files with a hashbang prepended onto it. I first learned about them in this YouTube video. Here is the documentation. If you open a PEX file without any arguments, it will open a Python interpreter with whatever modules it was bundled with. If you give it a Python script it will run that script with whatever modules it was bundled with.

Installation

I had to install wheels before I could install PEX.

pip install wheel
pip install pex

Example

Suppose you have your own package with the following structure:

myStuff/
|--myStuff/
|  |--__init__.py
|  `--myStuff.py
`--setup.py

We’ll assume that your setup.py script looks like this,

#!/usr/bin/env python

from setuptools import setup, find_packages

setup(
    name="myStuff",
    version="1.1",
    author="Mr. Coffee",
    description="A simple PEX example",
    install_requires=['weirdStuff'],
    packages=find_packages()
)

We’ll assume further that you’ve organized myStuff.py as a bunch of functions, a main() function and an if __name__=="__main__": statement, like this,

#!/usr/bin/env python

import weirdStuff

def fct_1():
    pass

def fct_2():
    pass

def main():
    fct_1()
    fct_2()

if __name__ == "__main__":
    main()

Then we can build a PEX file by requiring weirdStuff, sourcing the myStuff package, and executing the myStuff.main() by specifying that endpoint,

pex -r weirdStuff -s myStuff -e myStuff.myStuff:main -o out.pex

So, the -r flag requires weirdStuff, the -s flag sources your package, and the -e flag specifies the endpoint–that means that after weirdStuff and myStuff is imported, myStuff.myStuff.main() is called. Now you can shoot this guy to a colleague and they can execute it by calling ./out.pex at the command line, assuming that they have Python installed.