5

I have a python script which makes a GUI. When a button 'Run' is pressed in this GUI it runs a function from an imported package (which I made) like this

from predictmiP import predictor
class MiPFrame(wx.Frame):
    [...]
    def runmiP(self, event):
         predictor.runPrediction(self.uploadProtInterestField.GetValue(), self.uploadAllProteinsField.GetValue(), self.uploadPfamTextField.GetValue(), \
                   self.edit_eval_all.Value, self.edit_eval_small.Value, self.saveOutputField)

When I run the GUI directly from python it all works well and the program writes an output file. However, when I make it into an app, the GUI starts but when I press the button nothing happens. predictmiP does get included in build/bdist.macosx-10.3-fat/python2.7-standalone/app/collect/, like all the other imports I'm using (although it is empty, but that's the same as all the other imports I have).

How can I get multiple python files, or an imported package to work with py2app?

my setup.py:

""" This is a setup.py script generated by py2applet

Usage: python setup.py py2app """

from setuptools import setup

APP = ['mip3.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

edit:

It looked like it worked, but it only works for a little. From my GUI I call

 blast.makeBLASTdb(self.uploadAllProteinsField.GetValue(), 'allDB')

 # to test if it's working
 dlg = wx.MessageDialog( self, "werkt"+self.saveOutputField, "werkt", wx.OK)
 dlg.ShowModal() # Show it
 dlg.Destroy() # finally destroy it when finished.

blast.makeBLASTdb looks like this:

def makeBLASTdb(proteins_file, database_name):  
    subprocess.call(['/.'+os.path.realpath(__file__).rstrip(__file__.split('/')[-1])+'blast/makeblastdb', '-in', proteins_file, '-dbtype', 'prot', '-out', database_name])

This function gets called, makeblastdb which I call through subprocess does output a file. However, the program does not continue,

dlg = wx.MessageDialog( self, "werkt"+self.saveOutputField, "werkt", wx.OK)
dlg.ShowModal() # Show it

in the next lines never gets executed.

Niek de Klein
  • 8,524
  • 20
  • 72
  • 143

2 Answers2

11

py2app (or rather, setup.py) doesn't magically include files, just because you import them in your application code.

From your description it's not quite clear to me where the predictmiP.py file is located, where the mip3.py file is located, where the setup.py file is located, and how the rest of the directory tree looks.

So, a few general notes on packaging Python files (see also http://docs.python.org/2.7/distutils/index.html). If you just have a few files, you can list them explicitly:

setup(
    py_modules=['file1', 'file2']
)

This would include file1.py and file2.py. If you have lots of files, that gets tedious, of course, so you can tell setup.py to include all Python files it finds, like so:

setup(
    package='example',
)

This expects a directory named example, containing an __init__.py, and will include all Python files found there.

If you have a different directory layout, e.g. a src directory containing the Python files, set it like this:

setup(
    package='example',
    package_dir={'': 'src'}
)

This expects a directory src/example, and includes the Python files below there.

wosc
  • 2,169
  • 1
  • 13
  • 9
  • 1
    py2app does "magically" include modules and packages after you run `python setup.py py2app` to construct a bundle. It doesn't include in the setup.py, but should in the final bundle. But I'm not exactly sure if did he build a bundle or not. – mmgp Dec 09 '12 at 12:59
  • The adding the python package is working, I'm having a different problem with the app not continuing after a command line tool is finished, but I'll need to make a different question for that. Thanks for your answer. – Niek de Klein Dec 09 '12 at 23:30
7

Since your setup.py is not provided, I will guess it does not resemble something like:

from setuptools import setup

OPTIONS = {'packages' : ['predictmiP']}

setup(app=someapp.py, options={'py2app' : OPTIONS},
      setup_requires=['py2app'])

Or maybe you are looking for OPTIONS['includes'] ? Or maybe OPTIONS['frameworks'] ?

mmgp
  • 18,901
  • 3
  • 53
  • 80
  • that did it.. thanks! so I have to add every package I want to import to the packages list? – Niek de Klein Dec 06 '12 at 00:17
  • Until you added your setup.py, I had no idea you were using py2app. Then after I saw you were using py2app, I got a little confused because it should detect imported packages/modules and include them in the bundle. Do you get the error when running the bundle generated by `python setup.py py2app` ? It could be a py2app bug. On the other hand, I find this to be a good thing in general simply because I prefer to directly specify what I'm using rather than wasting time with dependency trackers. – mmgp Dec 06 '12 at 00:49
  • No I don't, the program just starts up but when I press the run button it doesn't do anything. Now that I use the package option it does – Niek de Klein Dec 06 '12 at 10:48