I am trying to embed an AppleScript in a Python script. I don\'t want to have to save the AppleScript as a file and then load it in my Python script. Is there a way to enter
In python 3 it would be slightly different:
script = 'tell "some application" to do something'
p = Popen(['osascript', '-'], stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
stdout, stderr = p.communicate(script)
Popen now expects a byte-like object, to pass a string, the universal_newlines=True
parameter is needed.
Example 3 in this article suggests:
#!/usr/bin/env python
#sleepy-mac.py
#makes my mac very sleepy
import os
cmd = """osascript -e 'tell app "Finder" to sleep'"""
def stupidtrick():
os.system(cmd)
stupidtrick()
These days, however, subsystem.Popen
is usually preferred over os.system
(the article is from three years ago, when nobody screamed on seeing an os.system
call;-).
Rather than embedding AppleScript, I would instead use appscript. I've never used the Python version, but it was very nice in Ruby. And make sure that, if you're installing it on Snow Leopard, you have the latest version of XCode. However, I've so far been unable to install it on Snow Leopard. But I've only had Snow Leopard for ~1 day, so your mileage may vary.
See https://pypi.org/project/applescript/
import applescript
resp = applescript.tell.app("System Events",'''
set frontApp to name of first application process whose frontmost is true
return "Done"
''')
assert resp.code == 0, resp.err
print(resp.out)
etc. Most of suggestions, including "applescript" I quoted, are missing one important setting to osascript -- setting an -s option to "s", otherwise you will be having difficulty parsing the output.
Use subprocess:
from subprocess import Popen, PIPE
scpt = '''
on run {x, y}
return x + y
end run'''
args = ['2', '2']
p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)
Here's a generic function in python. Just pass your applescript code with/without args and get back the value as a string. Thanks to this answer.
from subprocess import Popen, PIPE
def run_this_scpt(scpt, args=[]):
p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
return stdout
#Example of how to run it.
run_this_scpt("""tell application "System Events" to keystroke "m" using {command down}""")
#Example of how to run with args.
run_this_scpt('''
on run {x, y}
return x + y
end run''', ['2', '2'])