API for Apple Numbers

I am trying to automate some processes for me. What I am trying to do is to automate the date upload to Apple Numbers from my Python application. So I just wanted to ask if Apple provides some kind of API to access Numbers? just like Google provides an API to access Google sheets.

Thanks.

Servers/Datacom

Posted on Jun 22, 2020 10:29 AM

Reply
Question marked as Top-ranking reply

Posted on Jun 22, 2020 3:44 PM

You can access Numbers with a regular AppleScript HERE document and then launching via a subprocess. You will need to obey the AppleScript dictionary properties for the Numbers application, which are found in Scripting Dictionary : File menu : Open Dictionary… Numbers.


Here is sample code that will automatically open Numbers, create a new spreadsheet, name new sheets after the months of the year, and then save and close the Numbers application to the Desktop. Standard error is directed to /dev/null. Tested with Numbers 10 on macOS Mojave 10.14.6 (18G5033). Tested: Python 2.7.16, and 3.8.3.


#!/usr/bin/env python
#

import subprocess
import os
import sys

try:
    from subprocess import DEVNULL  # python3
except ImportError:
    DEVNULL = open(os.devnull, 'wb')

AS = '''
-- AppleScript to open new Numbers spreadsheet and auto-populate new tabs with month names
set monthnames to {}
set filePath to ((path to desktop as text) & "month_sheets.numbers") as text

set {TID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
set docStr to last item of (text items of filePath)
set AppleScript's text item delimiters to TID

-- build dynamic table of month names
repeat with i from 1 to 12
    set datestr to "" & i & "/1/2018"
    copy (month of date (datestr)) as text to the end of monthnames
end repeat

tell application "Numbers"
    activate
    set thisDocument to make new document with properties {name:docStr}
    tell thisDocument
        repeat with amonth in monthnames
            repeat 1 times
                if amonth contains "January" then
                    set the name of sheet 1 to amonth
                    exit repeat
                end if
                make new sheet with properties {name:amonth}
            end repeat
        end repeat
    end tell
    close thisDocument saving yes saving in file filePath
end tell
tell application "Numbers" to if it is running then quit
return
'''


def main():
    try:
        # pass a PDF into Automator and use the Extract PDF Text action
        # set to overwrite the same name with .txt extension
        subprocess.check_output(["osascript", "-e", AS], stderr=DEVNULL)
    except subprocess.CalledProcessError as e:
        print('Python Error: [%d]\n{!r}'.format(e.returncode, e.output))
        sys.exit(1)


if __name__ == '__main__':
    sys.exit(main())


4 replies
Question marked as Top-ranking reply

Jun 22, 2020 3:44 PM in response to fakhar82

You can access Numbers with a regular AppleScript HERE document and then launching via a subprocess. You will need to obey the AppleScript dictionary properties for the Numbers application, which are found in Scripting Dictionary : File menu : Open Dictionary… Numbers.


Here is sample code that will automatically open Numbers, create a new spreadsheet, name new sheets after the months of the year, and then save and close the Numbers application to the Desktop. Standard error is directed to /dev/null. Tested with Numbers 10 on macOS Mojave 10.14.6 (18G5033). Tested: Python 2.7.16, and 3.8.3.


#!/usr/bin/env python
#

import subprocess
import os
import sys

try:
    from subprocess import DEVNULL  # python3
except ImportError:
    DEVNULL = open(os.devnull, 'wb')

AS = '''
-- AppleScript to open new Numbers spreadsheet and auto-populate new tabs with month names
set monthnames to {}
set filePath to ((path to desktop as text) & "month_sheets.numbers") as text

set {TID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
set docStr to last item of (text items of filePath)
set AppleScript's text item delimiters to TID

-- build dynamic table of month names
repeat with i from 1 to 12
    set datestr to "" & i & "/1/2018"
    copy (month of date (datestr)) as text to the end of monthnames
end repeat

tell application "Numbers"
    activate
    set thisDocument to make new document with properties {name:docStr}
    tell thisDocument
        repeat with amonth in monthnames
            repeat 1 times
                if amonth contains "January" then
                    set the name of sheet 1 to amonth
                    exit repeat
                end if
                make new sheet with properties {name:amonth}
            end repeat
        end repeat
    end tell
    close thisDocument saving yes saving in file filePath
end tell
tell application "Numbers" to if it is running then quit
return
'''


def main():
    try:
        # pass a PDF into Automator and use the Extract PDF Text action
        # set to overwrite the same name with .txt extension
        subprocess.check_output(["osascript", "-e", AS], stderr=DEVNULL)
    except subprocess.CalledProcessError as e:
        print('Python Error: [%d]\n{!r}'.format(e.returncode, e.output))
        sys.exit(1)


if __name__ == '__main__':
    sys.exit(main())


Jun 23, 2020 4:22 AM in response to VikingOSX

If you don't like ballooning your Python code with AppleScript, you can read the appropriate AppleScript into a variable and pass that to subprocess. In the following example, I have a separate AppleScript file in the same location as the Python script, and that contains the relevant code from the preceding example.


Apologies for not removing the previous examples comment about passing a PDF into Automator. The perils of copy/paste…


#!/usr/bin/env python3
#
# Create a new Numbers document, create twelve new sheets with month names, close and quit.

import subprocess
import os
import sys

try:
    from subprocess import DEVNULL  # python3
except ImportError:
    DEVNULL = open(os.devnull, 'wb')


def main():
    try:
        ascript = os.path.expanduser('./nbr.applescript')
        with open(ascript, "r") as f:
            AS = f.read()
        # submit an AppleScript background process
        subprocess.check_output(["osascript", "-e", AS], stderr=DEVNULL)
    except subprocess.CalledProcessError as e:
        print('Python Error: [%d]\n{!r}'.format(e.returncode, e.output))
        sys.exit(1)


if __name__ == '__main__':
    sys.exit(main())


This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

API for Apple Numbers

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.