Looking forward to scripting

I didn’t mean to ruin Clark’s evening with this tweet. I thought he knew that Hamish Sanderson had stopped developing appscript and was telling people to stop using it on new projects.

@macdrifter Um, doesn’t Devon know that appscript has been end-of-lifed? appscript.sourceforge.net/status.html
  — Dr. Drang (@drdrang) Wed Mar 7 2012

(The tweet, by the way, was a reaction a link by Gabe [@macdrifter] to this entry in DEVONtechnologies’ blog. They apparently hadn’t heard about appscript being abandoned, either.)

Appscript was—and still is—a library for writing scripts that use Apple Events without having to write in AppleScript. There were actually three versions of the appscript library, one each for Python, Ruby, and Objective C. Clark and I were both users of the Python flavor.1

Appscript still works, and will almost certainly continue to work under Lion. But the Carbon API it depends on has been deprecated by Apple since Snow Leopard, so there’s no guarantee it’ll keep working beyond Lion. Sanderson was hoping that the replacement Cocoa APIs would gain the capabilities he needs to keep appscript working, but he’s now given up that hope. It’s a shame.

For me, the great advantage of using appscript was that I didn’t have to abandon the pleasant syntax and powerful text manipulation features of Python just to send a few Apple Events. I still struggled sometimes with the appscript syntax, but most of that was due to the underlying AppleScript syntax of the application I was trying to communicate with. My first use of appscript was back in 2007, and I was still using it in November of last year. By January, though, I’d learned that Sanderson was telling users to avoid it for new projects, and I did.

So what now? AppleScript is no substitute for Python, but without appscript Python is no substitute for AppleScript, either. I’ll have to render unto Caesar and use both. Most likely, I’ll write and debug the AppleScript parts in the AppleScript Editor, paste them into my Python scripts as multiline strings, and execute them from within Python via subprocess calls to the osascript command.

A simple example would be something like this:

python:
#!/usr/bin/python

from subprocess import *

ascript = '''tell application "Safari"
  get URL of front document
end tell'''

frontURL = Popen(['osascript', '-'], stdin=PIPE, stdout=PIPE).communicate(input=ascript)[0]

print "The page is from", frontURL.split('//')[1].split('/')[0]

I’m not a big fan of the subprocess syntax, but I can live with it.

Gabe has responded to Clark’s post with a prediction that all languages for the Mac between Automator at the low end and Objective C at the high end are in danger of being scrapped by Apple. This is even more dire than his comment here a couple of weeks ago Despite the threat from sandboxing and the lack of recent improvements to AppleScript, I think he’s too pessimistic. OS X is still Unix, and Unix is a programmer’s environment. Unless Apple takes away the Terminal, we’ll still be able to write scripts.

And as for AppleScript, I still say Apple won’t get rid of it without plenty of notice and probably not without an alternative way—apart from Objective C—to handle Apple Events. Apple’s been pushing scriptability for Mac applications for too long to drop it suddenly. This is one situation for which Steve Jobs’ absence works in our favor: Apple won’t be as mercurial without him.

And if I’m wrong about all this? Well, I switched from the Mac to Linux once. If necessary, I can do it again.


  1. Clark was a real master with appscript and Python. His blog is full of examples I learned from. 


6 Responses to “Looking forward to scripting”

  1. Carl says:

    Here’s a quick convenience module to save in your Python directory:

    from subprocess import Popen, PIPE
    
    def run_applescript(script):
        "Returns the result of running string in osascript (Applescript)"
    
        if hasattr(script, "encode"): #Assumes Python 3
            script = script.encode("utf-8")
    
        osa = Popen(["osascript", "-"], stdout=PIPE, stdin=PIPE, stderr=PIPE)
        results, err = osa.communicate(script)
    
        if err:
            raise Exception(err)
    
        return results.decode("utf-8")
    
  2. Macdrifter says:

    I’ve had some time to learn a bit more AppleScript-ObjC and it doesn’t make sense to me. It’s really just slightly more readable ObjC. I can’t imagine Apple would be happy to continue to support AppleScript just for this minor variation on ObjC. I’ve changed my mind about AS-ObjC. It’s just a bridge to get people over to native Cocoa and off of AS.

    I’m no expert, but the only real enhancements I’ve seen in AppleScript is giving it a way to call native Cocoa. That sounds like a no enhancement at all.

    I also agree that the terminal will always be there. The question is, how much of the AppScript functionality could ever exist in a post Mountain Lion world. Sure, OS modules might be able to still do some magic but there’s no telling what part of the OS file system will still be available when every app starts storing versions in an iCloud centric file system. I’m not looking forward to the Inception model of scripting where we need to start calling Cocoa code from Python or AS inside the shell.

    For what it’s worth, a comment on my post pointed out that a number of OS services rely on Perl. I also know a number of them use Python and Ruby too. I don’t think that would stop Apple from erecting security walls that block scripting languages from accessing apps and the filesystem.

  3. Clark says:

    I had actually used lightly Appscript in Obj-C too. But the Xcode 4 update broke it and I never could get it to build right thereafter. It was always much more of a hassle using in Obj-C than in Python though which was why I stayed in Python.

    At this stage I’d like to hear if Appscript works in Mountain Lion. I’m loath to change but I use a lot of scripts in my workflow and I’d hate to have to rewrite them all just to upgrade. It’s not like I have a lot of free time as is. (Although admittedly writing some goofy script has been a way to clear my mind in the evening which is how a lot of my blog posts arise)

    As I’ve said in a few places I think Apple is coming up with an Applescript alternative. That is there will be a general inter-application framework that will work on both iOS and OSX. I think that’s appropriate. But I don’t think Apple really knows yet what it will be. (Look at how the sandbox has had to change due to developer feedback) However inter application communication ala Android or WinPhone7 is clearly something that not only iOS is weak in but OSX is as well. (I like Services but they only recently got much love since the NeXTStep days and they really are insufficient for a lot of tasks)

    What’s frustrating is that Apple doesn’t have its solutions completed and what they’ve depreciated doesn’t have equivalents yet. It makes life very hard in various niches.

  4. Paul says:

    http://lists.apple.com/archives/applescript-implementors/2010/Jan/msg00044.html

  5. Clark says:

    I’d feel better if that post were from 2012 rather than 2010. Still I suspect the Carbon stuff will remain until an alternative is in place. The real issue is less Apple than it is Appscript itself. As I mentioned already I can’t get the Obj-C version to build in Xcode 4. (Admittedly I didn’t spend a long time trying) That’s the danger in using code that’s not supported.

  6. Dr. Drang says:

    Apparently Hamish (who started the thread Paul linked to) held out hope for quite a while before deciding that he couldn’t continue appscript.