Slide 1

Slide 1 text

Packaging with PyInstaller Glenn Ramsey Kiwi Pycon 2014

Slide 2

Slide 2 text

What it does Makes the application independent Gathers python files and dependencies Embeds python interpreter and libraries Source is not included Does not actually create an installer!

Slide 3

Slide 3 text

Where it can be used Windows + OS X + Linux + … Licensing PyInstaller itself – GPL >=2 Packaged program – Your choice Python 2.4 – 2.7 ( 3 - real soon now) Well documented

Slide 4

Slide 4 text

Alternatives Py2exe - Windows Py2app - OS X BbFreeze - Win + OS X + Linux CxFreeze – Win + OS X + Linux (Python 3)

Slide 5

Slide 5 text

How it works When launched a bootloader is started first. Bootloader Creates Python environment Starts Python interpreter Runs your program

Slide 6

Slide 6 text

How to use it onefile and onedir (default) modes python -o pyinstaller.py /path/to/main.py On first run it will create a spec file, then use: python -o pyinstaller.py /path/to/main.spec

Slide 7

Slide 7 text

A .spec file – analysis a = Analysis(myscript.py,...) Analyses imports Produces: a.scripts the python scripts named on the command line a.pure pure python modules needed by the scripts a.binaries non-python modules needed by the scripts

Slide 8

Slide 8 text

A .spec file – pyz and exe pyz = PYZ(a.pure) Creates a compressed archive containing pure python modules exe = EXE(pyz, a.scripts + options, ...) Creates an executable with the embedded python interpreter

Slide 9

Slide 9 text

A .spec file – Collect and Bundle coll = Collect(exe, a.binaries, a.zipfiles, a.datas, ...) Collects all files into a single directory app = Bundle(coll, name='MyApp' icon='/path/to/icon') OSX only – creates the app bundle

Slide 10

Slide 10 text

The TOC class (name, path, typecode) Typecodes: “DATA”, “BINARY”, “OPTION” Use to add or remove Modules Options

Slide 11

Slide 11 text

Including files Create a TOC – a tuple will suffice extra = [("defaults.cfg", os.path.join('..', 'GUI', 'defaults.cfg'), "DATA")] coll = collect(..., a.datas + extra) Can't include files outside the app dir Problem for OS X therefore use the build system

Slide 12

Slide 12 text

Excluding files a.binaries - [('badmodule', None, None)] a.binaries = [x for x in a.binaries if \ not x[0].startswith("scipy")] a.binaries = [x for x in a.binaries if \ Not os.path.dirname(x[1]).startswith( "C:\\Windows\\system32")]

Slide 13

Slide 13 text

Accessing files from a frozen app import sys import os ... if getattr(sys, 'frozen', False): # we are running in a |PyInstaller| bundle basedir = sys._MEIPASS if is_osx: res_path = os.path.join( sys._MEIPASS, "..", "Resources") else: # we are running in a normal Python env basedir = os.path.dirname(__file__)

Slide 14

Slide 14 text

OSX specific my.app Contents Frameworks Info.plist MacOS (executable) (shared libs) Resources Plugins

Slide 15

Slide 15 text

OSX specific files outside the bin dir e.g. plugins - use Cmake - use install_name_tool Info.plist LSBackgroundOnly

Slide 16

Slide 16 text

Hooks Example: countrycode module Collects the file countrycode_data.csv from site-packages from PyInstaller.hooks.hookutils import collect_data_files datas = collect_data_files('countrycode')

Slide 17

Slide 17 text

Hidden Imports For imports that PyInstaller can't find e.g. inside a function definition Can be used to workaround broken hooks Or just to force an import

Slide 18

Slide 18 text

Setting an icon Pass the icon path as a parameter to: the EXE class - Windows The Bundle class – OSX ..., icon = '/path/to/icon', ...

Slide 19

Slide 19 text

Actually creating an installer OSX – Drag'n'Drop or PackageMaker Windows - NSIS installer Linux - deb, rpm, bin Cmake / CPack

Slide 20

Slide 20 text

Using with a build system Cmake Use template to create main.spec with correct paths Create rules to run PyInstaller

Slide 21

Slide 21 text

Debugging 1. Check the log 2. -d – bootloader writes messages to stdout In spec file: Exe = EXE(..., debug = True, console = True) 3. If that doesn't work, then panic and get out the debugger. Live example - Simple PyQt5 application (wish me luck!) https://github.com/glennra/kpc2014

Slide 22

Slide 22 text

Support / Contributing Pyinstaller.org Mailing list Active development Patches accepted https://github.com/pyinstaller/pyinstaller

Slide 23

Slide 23 text

Thank you Acknowledgements PyInstaller team DigitalRowing Ltd