Running interactive Python script through Automator.

I have an interactive Python script that requires user text input to run. When I open the script in IDLE and run it I get a terminal window to enter text. When I 'package' this script inside of an Automator Application the terminal window does not open, and I get an error because the code is missing user input.


Is there any way to start an interactive shell session that the Python script can use?

Posted on Jan 5, 2023 8:48 AM

Reply
Question marked as Top-ranking reply

Posted on Jan 5, 2023 11:01 AM

Automator has a Text: Ask for Text action that takes a single input from a pop-up dialog and then passes that to the next action. You just access that user text string from your Python sys.argv[1:] arguments.


A little more advanced is to ask Python to run an AppleScript HERE document in a subprocess and capture the user input from that display dialog panel. But if you are seeking a single user input, the Automator Ask for Text is simpler to implement.


Python's Idle is useful for debugging Python code before it goes into an Automator Run Shell Script, but otherwise has nothing to do with Automator behavior.

6 replies
Question marked as Top-ranking reply

Jan 5, 2023 11:01 AM in response to retawater

Automator has a Text: Ask for Text action that takes a single input from a pop-up dialog and then passes that to the next action. You just access that user text string from your Python sys.argv[1:] arguments.


A little more advanced is to ask Python to run an AppleScript HERE document in a subprocess and capture the user input from that display dialog panel. But if you are seeking a single user input, the Automator Ask for Text is simpler to implement.


Python's Idle is useful for debugging Python code before it goes into an Automator Run Shell Script, but otherwise has nothing to do with Automator behavior.

Jan 5, 2023 7:19 PM in response to retawater

When you run Python within an Automator Run Shell Script, its only means to interactively communicate with a user is via a graphical interface that it controls, or receiving command line arguments via the pass input : as arguments configuration in the Run Shell Script that are sys.argv[1:] arguments passed into it. That AppleScript display dialog, being ancient technology, can only prompt for one user input per dialog instance, or multiple, if you instruct the user to enter multiple answers punctuated by a character that Python can split into an array of user inputs.


It is late, I will see if I can post an example tomorrow.



Jan 6, 2023 8:31 AM in response to retawater

Here is an example of passing a value to an AppleScript, and retrieving values from user input via a Python3 subprocess invocation:


#!/usr/bin/env python3

import subprocess
import sys
import os
import re

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

#!/usr/bin/python
# coding: utf-8

import os
import sys
import subprocess

ascript = '''
use scripting additions
on run argv

    display dialog "current directory location is: " & (item 1 of argv) with title "Passed argument"

    try
        set query to text returned of (display dialog "Enter your name, rank, and serial number each separated by a single semi-colon (;) : " default answer "")
    on error -128
        return "Cancel"
    end try
    if not query = "" then
     return query
    else
        return "Invalid User Input"
    end if
end run
'''


def main():
    os.chdir(os.path.dirname(__file__))
    thisdir = os.getcwd()
    try:
        proc = subprocess.check_output(['osascript', '-e', ascript, thisdir],
                                       shell=False, stderr=DEVNULL)

        if 'Cancel' in proc.decode('utf-8'):  # User pressed Cancel button
            sys.exit(proc.decode('utf-8'))
        elif 'Invalid User Input' in proc.decode('utf-8'):
            sys.exit(proc.decode('utf-8'))
    except subprocess.CalledProcessError as e:
        print('Python error: [%d]\n%s\n'.format(e.returncode, e.output))
    
    # split user input on semi-colon
    details = proc.decode('utf-8').split(';')

    if not details:
        print("empty user input")
    elif len(details) == 3:
        print("{}\t{}\t{}".format(*details))
    else:
        print("User did not input all three requests")
   

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


Jan 5, 2023 3:05 PM in response to VikingOSX

Thanks. I left out some details in my question, and I think the subprocess option will work better. Depending on the user, the script does not always ask for input. So I would like to have the Python script trigger the subprocess only when necessary. Also there are multiple arguments that will be passed into the Python script.


Can you point me to any resources to learn about how to implement this subprocess? It is beyond my experience in Python.

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.

Running interactive Python script through Automator.

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