Using Python and AppleScript Together
Pages: 1, 2
Here is another way to call AppleScript within Python code.
Example 4: Call AppleScript from Python with HEREDOC
import os #An example of the HEREDOC method cmd = """osascript<<END tell application "iTunes" play playlist "Party Shuffle" end tell END""" def play_iTunes(): os.system(cmd) play_iTunes()
Notice that with osascript you can triple quote osascript and embed a huge complicated AppleScript. This can be a pretty effective way to use AppleScript in Python as you could even throw several osascripts into a list or dictionary and call them throughout a Python script.
Let's make this example a little more cool though. What if you just bought an expensive, fully loaded, MacBook Pro, you have no more money in the bank, and your alarm clock breaks. Well, you can write a script for your daily alarm clock. Here's how:
Step 1: Open up Automater and select "Run Shell Script"
Step 2: Select the Python shell.
Step 3: Paste in code from example 4.
Figure 1: Running a shell script in Automator
Step 4: Press Run and test it out.
Step 5: Save it as an application called automater-itunes-pmix inside of your home directory sandbox.
That's all it takes to create a full application using Automator. Now let's be smart and think of how to we can reuse this application again for more than just an alarm clock. If you are thinking, "Let's make an alias to this in .profile," you're right!
I created another section just for automator applications:
### Automator-commands alias pmix='open ~/sandbox/itunes-itunes-pmix.app/'
Figure 2: bash Profile
Now if you type this in a new shell (remember every change to .profile requires a new shell to see the change):
pmix alias pmix='open ~/sandbox/itunes-itunes-pmix.app/'
your Mac will automatically launch iTunes and play a party mix. Now we're talking...that is sweet!
Step 6: Open up System Preferences-Energy Saver, and select the Schedule button. You will see a startup or wake at dialog. Select the time you want to wake up.
In order for your machine to act as an alarm clock you must do two other things.
Step 7: Turn on Autologin for you account. Go to System Preferences>Accounts>your username>login options.
Figure 3: Automatic Login Enabled
Step 8: Create a login item for your profile.
Figure 4: Login for Alarm Clock
Step 9: Test it! Shut down your computer and turn the power back on. You should have a party mix automatically play.
Step 10:; Test it again! Change the wake up/power on clock time to a few minutes in the future and turn your computer off.
Once that works, you should pat yourself on the back. You just built your own customized alarm clock and command party mix tool in one shot!
Another intersting way to interact with Python is to pass a variable from Python into AppleScript:
Type in a shell (remember you created the bash alias, if you're following along from home):
Example 5: Pass a Python value to an AppleScript variable
This one line Python script will find your hostname and pass it to AppleScript, which will then create a pop-up dialog box with your hostname. Paste inside of the Script Editor and run:
set hostname to (do shell script "python -c 'from socket import gethostname; print gethostname()'") display dialog "Your hostname is: " & hostname
Note: I borrowed this one liner from the python wiki.
So we have some fun, useable techniques, but I think in some cases there is a better way. It is time to introduce appscript.
What Is Appscript?
Appscript is a Python bridge to AppleScript. It translates the functionality of AppleScript into the Python language. Basically, it makes AppleScript Pythonic, by allowing it to execute as Python code and eliminating much of the verbosity of the language. Appscript, in turn, allows you interact with a higher level API to the Apple User Interface that would be possible from the python standard library. Finally, appscript is a viable alternative to AppleScript.
You can download appscript from http://appscript.sourceforge.net/
To use appscript you need to download appscript, HTMLDictionary, and ASTranslate. Appscript is the actual bridge from Python to AppleScript. HTMLDictionary formats AppleScript dictionaries to appscript documentation for that object which is quite handy for reference! ASTranslate will try to translate AppleScript code into an appscript version. The good news is that is mostly works.
Below is an example of an appscript I wrote:
Example 6: Fully scripting a third-arty application with appscript
#!/usr/bin/env pythonw #Automates Diskwarrior Application through appscript from appscript import * import time #A function to fully automate Diskwarrior Application def diskwarrior(): t0 = time.time() #Tells Diskwarrior to start with a timeout of 3600 sec. app(u'/Applications/DiskWarrior.app').activate(timeout=3600) #Tells diskwarrior to rebuild disk. app(u'/Applications/DiskWarrior.app').disk['main'].rebuild(replacing=k.yes_, timeout=3600) #Tells Diskwarrior to quit app(u'/Applications/DiskWarrior.app').quit(timeout=3600) print "It took this many seconds to run Diskwarrior on your hard drive: \n" print time.time()-t0 diskwarrior()
Example 7: AppleScript code comparison of DiskWarrior script
with timeout of 3600 seconds tell application "DiskWarrior" activate rebuild disk "main" replacing yes end tell tell application "DiskWarrior" quit end tell end timeout
Driving appscript with IPython
If you don't have IPython installed then you should do so now. You can download the source from http://ipython.scipy.org/moin/Download. Or you can do like I do and use easy_install, download the easy_install script from http://peak.telecommunity.com/DevCenter/EasyInstall
Then just type:
And from a shell type:
Now you are in IPython. At the IPython prompt, enter:
from appscript import *
Now you are ready to experiment with appscript using IPython. Let's start a slideshow:
We just launched a slideshow with one line of code. Touch a key on keyboard to come back to IPython.
That was fun. Now let's quit iPhoto. I am bored of seeing my vacation pics for the 1,200th time.
Poof! iPhoto is gone. Hmmm...what else can we play with? I always wonder what day of the week I was born on. I bet iCal can show me:
import datetime app(u'/Applications/iCal.app').view_calendar(at=datetime.datetime(1975, 5, 21, 0, 0))
So I was born on a Wednesday in 1975.
AppleScript can be clumsy and I think appscript is a little better, but the best approach to solve problems may be to combine appscript or AppleScript within your Python scripts. Please watch out for AppleScript event timeouts, as they can kill a script you thought would work.
In addition, since you need to deal with AppleScript inside of Python, special thought needs to go into how you write programs, as they won't behave as you would expect regular Python code to behave, due to the nature of Apple events.
We made some fun toys using AppleScript, appscript, and Python. We now have a way to open and close applications from the shell by typing in a three character alias. We created a sneaky, sleepymac command-line tool. And we made a full-fledged alarm clock application using several of the techniques we learned. Finally, we got into IPython and appscript to really mix it up.
Python is very powerful and robust, so only use appscript or AppleScript when you have to. When you write AppleScript code, think of how to make it generic enough that you can reuse it and call if from a bash alias.
IPython is really fun to play with and very powerful. IPython and appscript are a good combination. I hope this article has given you some good ideas. Now go automate things!
Here is your final exam. Download PagePacker and use appscript to automate the printing of several .png files onto one page. I will post one example of how to do so later on my blog.
Noah Gift is the co-author of Python For Unix and Linux by O'Reilly. He is an author, speaker, consultant, and community leader, writing for publications such as IBM Developerworks, Red Hat Magazine, O'Reilly, and MacTech, and Manning.
Return to MacDevCenter.com.