I’ve had Photoshop in mind since day 1 but always imagined an implementation would have to involve JavaScript or VBScript and never once considered it to be possible with Python.
But then I saw this.
And apparently it’s way possible and has been possible for almost a decade.
The challenge of integrating with Photoshop however lies in the fact that the Python-side isn’t integrated into the execution environment, which means Pyblish can’t either. Luckily, this isn’t as uncommon as I first thought. We’ve already experienced this with Modo, Softimage, Fusion and now Photoshop. Solving this for one, will likely pave the way for each of them.
I’ve got an idea for an implementation, but will need your help.
Basically, the Pyblish run-time needs to run within a Python environment. In case of Maya, Nuke and Houdini, this is straightforward as they each are providing the environment seamlessly within it’s own execution environment. What this means for Photoshop et. al. is that we are now looking at 2 separate processes running in tandem with the host.
This is how it looks currently, in Maya et. al.
And here’s how it will need to look like for Photoshop et. al.
Users interact with the GUI, and Pyblish interacts with the Python interpreter, whereas the Python interpreter interacts with the host.
The ingredients for this little adventure is this.
gui.py
import sys
import argparse
import xmlrpclib
parser = argparse.ArgumentParser()
parser.add_argument("publish", action="store_true")
args = parser.parse_args()
if args.publish is True:
# Connect with python.py
proxy = xmlrpclib.ServerProxy("http://127.0.0.1:9090")
if proxy.publish():
print("Successfully published!")
else:
print("Available argument is 'publish'")
middleman.py
import threading
from SimpleXMLRPCServer import SimpleXMLRPCServer
# Host-specific library
import host
def publish():
print("python.py publishing..")
if host.export_all():
return True
return False
server = SimpleXMLRPCServer(("127.0.0.1", 9090))
server.register_function(publish)
worker = threading.Thread(target=server.serve_forever)
worker.daemon = True
worker.start()
print("Listening on 127.0.0.1:9090")
host.py
import time
def export_all():
print("Exporting all..")
time.sleep(2)
print("Success!")
return True
Experiment
To test things out, open up two terminals and run middleman.py
and gui.py
.
Terminal 1
$ python middleman.py
Listening on 127.0.0.1:9090
Terminal 2
$ python gui.py publish
Attempting to publish..
Successfully published!
This emulates Pyblish QML (gui.py
), the individual process we would need to run in order to communicate with Photoshop (host.py
) and the connection with the host (middleman.py
).
If we can replace import host
from middleman.py
with a connection to Photoshop, and call an actual command instead of export_all()
, we’re done.
The same will then apply to Modo, Softimage and Fusion.
Anyone brave enough to give it a go?