5

I often use Applescript to accomplish basic tasks like opening and closing programs, sometimes going a little more in-depth like running a specific Xcode program's unit tests. I'm learning Python, and I love it. I haven't been able to find much documentation relating AppleScript to Python. My question is: On Mac OS X, can Python be used in place of AppleScript to accomplish the tasks mentioned above? And if so, does anyone know of a good resource to learn more about the topic?

5 Answers 5

3

Python can't be used to replace the UI & automation duties that AppleScript offers. However since OS X 10.10 (Yosemite) JavaScript can also be used.

See here: https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/index.html

Sign up to request clarification or add additional context in comments.

3 Comments

Using the AE modules in python will gain full control over applications just like AppleScript. So yes, it can fully replace AppleScript, including UI and automation. The syntax becomes more like JavaScript more about it here: docs.python.org/2/library/macosa.html
The AE modules in Python 2.x are crippled, crappy, and long broken. Don't waste your time on them (Python 3 dumped them entirely). The Python-appscript bridge is 99% as good as AppleScript itself, but is effectively legacied by Apple's War on Carbon, and I no longer provide support for it. OS X's Scripting Bridge framework is accessible via PyObjC, but it's crippled and crappy too; it may work for trivial tasks, but for anything non-trivial stick with AppleScript. Oh, and JavaScript for Automation is crippled and crappy too, plus its general library support is nothing compared to Python's.
Javascript JXA is in a pitiful state. If it were actively maintained it would have been great.
3

To avoid all the out-dated and so-called "crappy" modules including PyObjC, one can simply debug a script in the Script Editor or Script Debugger (my choice) and then execute it using osascript via Popen. I prefer this so I can ensure the idiosyncrasies of the applications implementation are worked around and Script Debugger has great debugging and browsing tools.

For example:

from subprocess import Popen, PIPE

def get_front_win_id():
    """
    Get window id of front Chrome browser window
    """
    script = '''
        on run {}
            set winID to 0
            tell application "Google Chrome"
                set winID to id of front window
                return winID
            end tell
        end run
    '''
    args = []
    p = Popen(['/usr/bin/osascript', '-'] + args,
              stdin=PIPE, stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate(script)
    winID = stdout.strip()
    return int(winID)

Pass args in a list to osascript but they have to be strings so complex data structures can be tedious to marshal and and unmarshal but there is a price for the simplicity. I left off error checking and exception handling/raising for simplicity. TANSTAAFL

Comments

3

While you can produce convoluted python that invokes the same Apple Events as AppleScript, some things are handled more easily in AppleScript.

It's easy enough to execute some AS in python though:

from Foundation import NSAppleScript
textOfMyScript = """
   *(Your AppleScript Here)*
"""
myScript = NSAppleScript.initWithSource_(NSAppleScript.alloc(), textOfMyScript)
results, err = myScript.executeAndReturnError_(None)

The results are an NSAppleEventDescriptor, if you need to get data out.

2 Comments

this seems to require pyobjc library
@JerryT PyObjC is included within MacOS. An old version, but the above script should work. Newer versions of PyObjc can be downloaded.
2

With Cocoa you can send events directly using AESendMessage. It is a lot more work though. Here is a gist which provides an example:

https://gist.github.com/pudquick/9683c333e73a82379b8e377eb2e6fc41

Comments

1

Can't really replace it but there is a wrapper available for it: https://pypi.python.org/pypi/py-applescript/1.0.0... so you can interact with it from within your python program.

1 Comment

Another, slicker, option is to use the PyObjC and AppleScriptObjC bridges, allowing Python to call AppleScript handlers directly. It's not perfect (e.g. dates and file objects aren't automatically bridged, so you'll need to fiddle a bit with those), but it works out of the box with Apple-supplied Python; no need to install additional libraries. See appscript.sourceforge.net/asoc.html for a quick HowTo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.