Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pyinstaller with a non-trivial directory structor

I have written a simple web application with embedded web server (tornado), database (sqlalchemy using sqlite for now), and the whole shabang. I would like to bundle it all up into a single self-contained directory with a single exe that can be run. The deployment scenario absolutely demands a one click install and run like this.

I have absolutely failed trying to get py2exe or pyinstaller to bundle up my code. The problem has directly to do with the directory structure and layout, which is as follows. I do not want to change the directory layout to much. Can someone suggest how I can get this with either py2exe or pyinstaller or any other suitable tool?

project/
|-> main.py

|-> libs/
    |-> tornado/ (The full git rep as a submodule)
        |-> tornado/ (The actual package)
    |-> sqlalchemy/

|-> src/
    |-> support-1.py
    |-> support-2.py

|-> static/
    -> js/
    -> img/
    -> css/

|-> templates/
like image 791
Karra Avatar asked May 21 '12 17:05

Karra


People also ask

Is there an alternative to PyInstaller?

The best alternative is nuitka, which is both free and Open Source. Other great apps like PyInstaller are py2exe, cx_Freeze, Shed Skin and bbfreeze. PyInstaller is a program that freezes (packages) Python programs into stand-alone executables, under Windows, Linux, Mac OS...

Does PyInstaller work with libraries?

PyInstaller does not include libraries that should exist in any installation of this OS. For example in GNU/Linux, it does not bundle any file from /lib or /usr/lib , assuming these will be found in every system.

Does PyInstaller need UPX?

PyInstaller looks for UPX on the execution path or the path specified with the --upx-dir option. If UPX exists, PyInstaller applies it to the final executable, unless the --noupx option was given. UPX has been used with PyInstaller output often, usually with no problems.

Why is the .exe file created by PyInstaller not working?

The most common reason a PyInstaller package fails is that PyInstaller failed to bundle a required file. Such missing files fall into a few categories: Hidden or missing imports: Sometimes PyInstaller can't detect the import of a package or library, typically because it is imported dynamically.


1 Answers

Well, sorry to answer my own question. But much googling and trial and error, I managed to get this working. I am pasting my setup.py (for py2exe) below for anyone who has similar issues getting tornado + sqlalchemy + sqlite working with py2exe. When I run python setup.py py2exe, the last lines mention that some module are missing. But this had no impact on the execution of the program.

> "['Carbon', 'Carbon.Files', '_curses', '_scproxy', 'django.utils',
> 'dummy.Process', 'pkg_resources', 'pysqlite2', 'simplejson',
> 'sqlalchemy.cprocessors', 'sqlalchemy.cresultproxy', 'tornado.epoll']"

Here is my setup.py:

import glob, os, sys

curr_dir = os.path.abspath('.')
pare_dir = os.path.abspath('..')

sys.path = [os.path.join(pare_dir, 'py2exe-0.6.9', 'py2exe'),
           os.path.join(curr_dir, 'src'),
           os.path.join(curr_dir, 'libs', 'tornado'),
           os.path.join(curr_dir, 'libs', 'sqlalchemy'),
           os.path.join(curr_dir, 'libs')] + sys.path


from distutils.core import setup
import py2exe

data_files = [('', ['config.json']),
              ('db', ['db/prs.db']),
              ('templates',      glob.glob('templates/*.*')),
              ('static',         glob.glob('static/*.*  ')),
              ('static/css',     glob.glob('static/css/*.*')),
              ('static/js',      glob.glob('static/js/*.*')),
              ('static/js/libs', glob.glob('static/js/libs/*.*')),
              ('static/img',     glob.glob('static/img/*.*')),
              ]

setup(console=['prs.py'], options={
    'py2exe' : {
        'includes' : ['demjson'],
        'packages' : ['sqlalchemy.dialects.sqlite'],
        }},
    data_files=data_files,
    )
like image 148
Karra Avatar answered Sep 20 '22 22:09

Karra