Here's a module I wrote. Make sure to use that -u argument to avoid buffering problems:
import os
import pickle
import subprocess
from subprocess import PIPE
import struct
import builtins
def call_thru_stream(stream,funcname,*args,**kwargs):
"""Used for calling a function through a stream and no return value is required. It is assumed
the receiving program is in the state where it is expecting a function."""
transmit_object(stream,(funcname,args,kwargs))
def function_thru_stream(in_stream,out_stream,funcname,*args,**kwargs):
"""Used for calling a function through a stream where a return value is required. It is assumed
the receiving program is in the state where it is expecting a function."""
transmit_object(in_stream,(funcname,args,kwargs))
return receive_object(out_stream)
#--------------------- Object layer ------------------------------------------------------------
def transmit_object(stream,obj):
"""Transmits an object through a binary stream"""
data=pickle.dumps(obj,2)#Uses pickle version 2 for compatibility with 2x
transmit_atom(stream,data)
def receive_object(stream):
"""Receive an object through a binary stream"""
atom=receive_atom(stream)
return pickle.loads(atom)
#--------------------- Atom layer --------------------------------------------------------------
def transmit_atom(stream, atom_bytes):
"""Used for transmitting a some bytes which should be treated as an atom through
a stream. An integer indicating the size of the atom is appended to the start."""
header=struct.pack("=L",len(atom_bytes))
stream.write(header)
stream.write(atom_bytes)
stream.flush()
def receive_atom(stream):
"""Read an atom from a binary stream and return the bytes."""
input_len=stream.read(4)
l=struct.unpack("=L",input_len)[0]
return stream.read(l)