Accessing Mac OS API’s with Python over AppleScript / Shortcuts

As a Python programmer; if you need to access a Mac OS API, the traditional way to go is to use the PyObjC library. However, this might be too cumbersome for simple tasks; such as getting the E-Mail address of a Mac contact.

For such small tasks, your Python code can simply make an AppleScript or Shortcuts call and get the result – without directly touching the API at all.

Here is a working example over AppleScript – but the same logic can be applied to Shortcuts as well.

AppleScript

Open your Script Editor app, and write the following code (obviously replacing the name + last name):

tell application "Contacts" to get value of email of first person whose first name is "Dr. Kerem" and last name is "Koseoglu"

When you run this script, you will hopefully see the E-Mail address of the given contact on the screen.

{"kerem@keremkoseoglu.com"}

Great! This means that, you can access your contacts over one line of code!

AppleScript (and Shortcuts) is a very comprehensive system, and the amount of things that you can do is virtually unlimited. Depending on the app you are accessing; you can create records, fetch data, do bulk operations and whatnot. Using the simple method in this article, you can do most of those via Python as well.

If the AppleScript code in question is too complicated, you can create an external AppleScript file and trigger it via Python as well.

Terminal

Before jumping to Python, we need to ensure that we can run this AppleScript command in the terminal. Luckily, Mac OS has a nice command line tool called osascript, which enables us this functionality.

Open a new terminal window, and enter the AppleScript command in the following manner:

osascript -e "tell application \"Contacts\" to get value of email of first person whose first name is \"Dr. Kerem\" and last name is \"Koseoglu\""

Hit enter, and you will hopefully see the E-Mail value on the terminal.

kerem@keremkoseoglu.com

Great! Now, let’s move on to the last step.

Python

Now, our Python task is very simple. All we need to do is to call the terminal command and fetch its output. Here is a sample Python script, which can return address, phone or E-Mail of the given Mac contact.

""" Mac contacts module """
import os

def test_contacts():
    """ Simple test """
    print(get_address("Dr. Kerem", "Koseoglu"))
    print(get_phone("Dr. Kerem", "Koseoglu"))

def get_address(name: str, surname: str) -> str:
    """ Returns the address of given person
    osascript -e "tell application \"Contacts\" to get formatted address
    of address of first person whose first name is \"Dr. Kerem\" and last name is \"Koseoglu\""
    """
    cmd = 'osascript -e "tell application \\\"Contacts\\\" to get formatted address'
    cmd += ' of address of first person whose first name is \\\"'
    cmd += name
    cmd += '\\\" and last name is \\\"'
    cmd += surname
    cmd += '\\\""'

    return _run_cmd(cmd)

def get_phone(name: str, surname: str) -> str:
    """ Returns the phone of given person """
    cmd = 'osascript -e "tell application \\\"Contacts\\\" to get value of phone'
    cmd += ' of first person whose first name is \\\"'
    cmd += name
    cmd += '\\\" and last name is \\\"'
    cmd += surname
    cmd += '\\\""'

    return _run_cmd(cmd)

def get_email(name: str, surname: str) -> str:
    """ Returns the E-Mail of given person """
    cmd = 'osascript -e "tell application \\\"Contacts\\\" to get value of email'
    cmd += ' of first person whose first name is \\\"'
    cmd += name
    cmd += '\\\" and last name is \\\"'
    cmd += surname
    cmd += '\\\""'

    return _run_cmd(cmd)

def _run_cmd(cmd: str) -> str:
    result = os.popen(cmd).read()
    result = result.replace("\n", " ")
    result = result.replace("  ", " ")
    return result

There are obviously better ways to run terminal commands and fetch results, but I leave that to you.

Shortcuts

Note that Apple has a new automation functionality called ShortCuts as well. The logic of this article applies there as well, because you can trigger a shortcut via the terminal. Example:

shortcuts run "Combine Images" -i ~/Desktop/*.jpg

Just call this command from Python like any other terminal command, and voila!


Posted

in

, ,

by

Tags:

Comments

Leave a comment