How to create Mac application bundle for Python script via Python
Asked Answered
A

3

4

I want to create a simple Mac application bundle which calls a simple Python script. I want to do that in Python.

Is there an easy way?

I tried to use py2app but that fails somehow, e.g.:

from setuptools import setup
setup(app=["foo.py"], setup_requires=["py2app"])

gives:

---------------------------------------------------------------------------
SystemExit                                Traceback (most recent call last)
/Users/az/<ipython console> in <module>()

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/core.pyc in setup(**attrs)
    138         ok = dist.parse_command_line()
    139     except DistutilsArgError, msg:
--> 140         raise SystemExit, gen_usage(dist.script_name) + "\nerror: %s" % msg
    141 
    142     if DEBUG:

SystemExit: usage: ipython [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
   or: ipython --help [cmd1 cmd2 ...]
   or: ipython --help-commands
   or: ipython cmd --help

error: no commands supplied
Type %exit or %quit to exit IPython (%Exit or %Quit do so unconditionally).

I also tried:

import py2app.build_app
py2app.build_app.py2app("foo.py")

which also doesn't work (TypeError: dist must be a Distribution instance) (I'm not really sure how to use py2app.build_app.py2app and also haven't really found much examples / documentation about it).

Maybe setuptools/py2app or so are anyway overkill for my use case. I just want to create a simple empty app bundle, copy a Python script into it and configure its Info.plist in such a way that it calls the Python script.

Assuntaassur answered 13/9, 2011 at 15:52 Comment(3)
Did you try following packages.python.org/py2app/tutorial.html#create-a-setup-py-file ? Because the steps you outline don't seem to reflect that or the setuptools tutorial.Tenenbaum
@Sii: I don't want to create a setup.py file. I want to do it from inside another Python script.Assuntaassur
One option is to use the OSX Automator: https://mcmap.net/q/389159/-how-to-create-a-mac-os-x-app-with-pythonTraveled
A
10

This is exactly what I wanted and works just fine:

#!/usr/bin/python

import sys
assert len(sys.argv) > 1

apppath = sys.argv[1]

import os, os.path
assert os.path.splitext(apppath)[1] == ".app"

os.makedirs(apppath + "/Contents/MacOS")

version = "1.0.0"
bundleName = "Test"
bundleIdentifier = "org.test.test"

f = open(apppath + "/Contents/Info.plist", "w")
f.write("""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleExecutable</key>
    <string>main.py</string>
    <key>CFBundleGetInfoString</key>
    <string>%s</string>
    <key>CFBundleIconFile</key>
    <string>app.icns</string>
    <key>CFBundleIdentifier</key>
    <string>%s</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>%s</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>%s</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>%s</string>
    <key>NSAppleScriptEnabled</key>
    <string>YES</string>
    <key>NSMainNibFile</key>
    <string>MainMenu</string>
    <key>NSPrincipalClass</key>
    <string>NSApplication</string>
</dict>
</plist>
""" % (bundleName + " " + version, bundleIdentifier, bundleName, bundleName + " " + version, version))
f.close()

f = open(apppath + "/Contents/PkgInfo", "w")
f.write("APPL????")
f.close()

f = open(apppath + "/Contents/MacOS/main.py", "w")
f.write("""#!/usr/bin/python
print "Hi there"
""")
f.close()

import stat
oldmode = os.stat(apppath + "/Contents/MacOS/main.py").st_mode
os.chmod(apppath + "/Contents/MacOS/main.py", oldmode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
Assuntaassur answered 13/9, 2011 at 16:37 Comment(1)
You could take a look at Platypus, which creates Mac application wrappers from interpreted scripts. sveinbjorn.org/platypusInchworm
B
4

Check out PyInstaller.

You give it the path to your python script and it analyzes all of your package imports, extracting any binary files that are needed and placing them into an archive.

I've used it for a fairly complex python program, and it worked for me.

Barocchio answered 13/9, 2011 at 15:55 Comment(5)
I don't want all that. I just want to create an empty app bundle.Assuntaassur
Then your app won't be portable.Barocchio
Why wouldn't it? See my own answer. That should be portable.Assuntaassur
What if the user has a different /usr/bin/python than what you expect? What if the user's python installation is missing a module you require?Barocchio
I'm only using standard (MacOSX) includes. Anyway, that is not really the scope of my question. Of course, if I would need additional stuff, I could add that.Assuntaassur
M
0

cxFreeze is best solution available as it is simple and time-saving.

first, create your program or application using python and then make setup file for your application.

And then build the app using build command python setup.py build, according to your requirement you need to make some changes, to make mac bundle or mac app refer this

Mismate answered 28/11, 2018 at 11:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.