This gist illustrates how two processes can exchange information via subprocess.Popen
.
Integrate an externally running user interface, potentially written in another language. For example, a GUI written in PyQt5 and Python 3 running inside of Autodesk Maya (Python 2.7, PySide).
child.py
is run via parent.py
and listens for input over stdin and sends requests to the parent process via stdout. The parent then emits data via the child-processes stdin and listens on it's stdout.
__________ _________
| | | |
| |--- stdin ----> |
| Parent | | Child |
| <--- stdout ---| |
|__________| |_________|
You'll need PyQt5 and Python 2.x in order to run this example.
$ git clone https://gist.github.com/a779958135b3659d639a.git bidir && cd bidir
$ python parent.py
There are two topics of communication on both ends.
request
: A process has transmitted outputresponse
: A process has produced output
Topics are distinguished by each line of communication being prefixed with either request:
or response:
. That way, both will know whether the incoming data is meant as a response to an earlier request, or as a request for something to do on behalf of the other.
The parent listens for requests only, but it's a good idea to listen for both in case the child has trouble performing a request and wishes to communicate an error of some kind.
Ths child listens on both requests and responses. Responses to requests transmitted to the parent are coming in via the child process's stdin
, whereas requests are made through its stdout
.
- A process won't output anything new unless the given
stdin
command ends with a newline - Synchronous request/reply is difficult, as they are both continously listen for input without considering where one "stream" begins or ends. It's arguable however whether one should bother designing for synchronousy when it comes to user interfaces as opposed to designing for asynchronousy. In this example,
update()
is sent from the child to the parent, but the child doesn't wait for input. Instead, the parent sends it whenever it can (without blocking itself either) and the child merely responds to the input. In that sense, it didn't matter that the child was the one who originally made the request.