Information exchange between Python and AppleScript

# You can quickly download the AppleScript <-> Python example here.

Since I first published AppleScript examples that made use of helping Python scripts I keep getting a lot of eMails from people who search for ways of combining the power of AppleScript and Python.

I can well understand their desire. AppleScript features some very unique inter-application automation possibilities on the Mac as well as cool techniques like folder actions and GUI scripting. Unfortunately its code is everything but short and sweet and lacks convenient goodies like classes and hash-tables.

In contrast, Python offers the finest in object-oriented programming and comes with a bucket full of handy ready-to-use libraries and modules following its ‘batteries included’ motto. So combining AppleScript and Python gives you the best from both worlds.

But when you are calling a Python script with arguments from your AppleScript or AppleScript Studio project, there are some pitfalls, which - fortunately - can be easily avoided. Also returning results from Python back to AppleScript is not always hassle free and can result in deep frustration.

AppleScript: Quote & convert to UTF-8

The most important thing to consider when executing a Python script from within AppleScript is to convert the whole «do shell script»-command to UTF-8 and to quote arguments where necessary. This, by the way, is not only important when executing Python scripts, but is in fact good practice whenever you are working with the «do shell script»-command in AppleScript:


set obscurechars to "åÅ"øΩ∫√"
set pyscriptpath to "/Users/martin/Desktop/pyscript.py"
-- quoting important arguments
set command to ("python " & quoted form of pyscriptpath & " " & quoted form of obscurechars)
-- converting the command to UTF-8
set command to command as «class utf8»
set shellresult to do shell script command

Converting the «do shell script»-command from AppleScript’s default text encoding UTF-16 to UTF-8 by using as «class utf8» ensures that all (special) characters (like German Umlauts) are safely transfered to the command line and imported by the Python script, provided the latter was created properly (I will describe how to do this later in this article).

Quoting arguments with AppleScript’s «quoted form of»-command ensures that passed arguments are not split into several parts if they contain spaces or other obscure characters. For example, not quoting the following file path, will lead to unwanted results:


set pyscriptpath to "/Users/martin/Desktop/pyscript.py"
set filepath to "/Users/martin/Desktop/file name with spaces.txt"
set command to "python " & pyscriptpath & " " & filepath
set command to command as «class utf8»
do shell script command

-- The Python script will import the following arguments
-- from the command line:
-- ['/Users/martin/Desktop/file', 'name', 'with', 'spaces.txt']

set filepath to quoted form of "/Users/martin/Desktop/file name with spaces.txt"

-- Using the «quoted form of»-command fixes this problem easily. Now the
-- Python script will import the argument properly:
-- ['/Users/martin/Desktop/file name with spaces.txt']

Now that we learned how to correctly call Python scripts with arguments from within AppleScript, let’s have a look at Python’s part of the communication.

Python: UTF-8 decoding and encoding

In our Python scripts, we have to decode the input gathered through «sys.argv» as UTF-8 first, before we can safely manipulate it. When we finally want to return our result back to AppleScript, the Python script needs once again to encode the output as UTF-8.

This simple sample script successfully imports an AppleScript argument, decodes the text, manipulates it and returns it back to AppleScript.

If you follow these simple rules, you won’t run into problems when combining the power of AppleScript and Python.

To show you the above mentioned theory also in practice, I have created an AppleScript sample application, which implements basic communication with a Python script. All the script files can be opened in the Script Editor or your favourite text editor to have a look at the source code. You can download the script here for free:

AppleScript <-> Python communication (ca. 44.6 KB)

Finally I want to point your attention to an amazing project, which is almost the perfect solution for everyone, who needs the unique features of AppleScript, but cannot cope with its syntax and programming language style:

appscript - a high-level, user-friendly Apple event bridge

Once installed on your Mac this fine module enables you to control scriptable Mac OS X applications using ordinary Python scripts. Unfortunately it does currently not allow you to easily use AppleScript’s simple GUI elements like «display dialog» or its unique folder action handlers «on adding folder items». But this is a minor tradeoff compared to the mighty tools it offers. I really recommend to give appscript a try. It made some of my programming tasks way easier.