XMLRPC call to unix command

In this example I like to demostrate how xmlrpc call could be used with python
to feed unix command with parameters. To make it simple the unix command is osascript.
The approach is not about doing the same with do shell script, its more about understanding how python works if we like to use unix command in the Pipe.

You also need this on top of the python script from subprocess import Popen, PIPE

The AppleScript will return 5 as string (2 + 3 = 5)

The XMLRPC server I use is Twisted (python module, read my other topic how to setup)

tell application "http://localhost:7080"
	set {stdin, stdout, stderr} to call xmlrpc {method name:"appleScript", parameters:{"2", "3"}}
	if stderr is "" then
		return stdout
	end if
end tell

Here is the function in python.

def xmlrpc_appleScript(self, *args):
        """
        """
        scpt = '''
            on run {x, y}
            return x + y
            end run
            '''

        a = [args[0], args[1]]
        p = Popen(['osascript', '-'] + a, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
        stdout, stderr = p.communicate(scpt)
        return (p.returncode, stdout.replace("\n", ""), stderr)
2 Likes

That’s a nice demo.

I couldn’t find your instructions in the “other” post, but I figured it out quickly myself. For anyone else to try this:

  1. In Terminal, create a new folder where you want to put your twisted installation and possibly also your python files. Go into that folder with the cd cmd.
  2. Install Twisted with the cmds that are listed on Twisted’s main page: virtualenv try-twisted ; . try-twisted/bin/activate ; pip install twisted[tls]
  3. Download the file xmlrpcserver.py as listed on Examples — Twisted 22.10.0 documentation and place it into the same folder.
  4. Edit xmlrpcserver.py:
    • Add the line from subprocess import Popen, PIPE below the other imports.
    • Insert the above python code, right before the line def main():, making sure the first inserted line is indented the same as the previous def xmlrpc_fail(self): above it, and that you leave a blank line after your paste, like this:
        …
        return Fault(7, "Out of cheese.")

    def xmlrpc_appleScript(self, *args):
        """
        See https://www.macscripter.net/t/xmlrpc-call-to-unix-command/74044
        """
        scpt = '''
            on run {x, y}
            return x + y
            end run
            '''

        a = [args[0], args[1]]
        p = Popen(['osascript', '-'] + a, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True)
        stdout, stderr = p.communicate(scpt)
        return (p.returncode, stdout.replace("\n", ""), stderr)

def main():
…
  1. Run the server with the cmd python xmlrpcserver.py.

Now run the AppleScript. It should give you the result “5”.

@tempel
Thanks for like it and also make it more clear ‘how to use’. And it was a little surprice to me that AppleScript had XMLRPC and SOAP support but I do recal I have read the documentation many years go but never understood what it ment.

There are many ways to run XMLRPC server so I guess it would also be possible in other situations. I have test on Node-Red that is event-driven communication in Node.JS.

1 Like