""" Util for talking to the client program in order to retrieve dynamic defaults for the UI """ import subprocess from json import JSONDecodeError from subprocess import CalledProcessError import os from gooey.python_bindings.types import Try, Success, Failure from gooey.python_bindings.coms import deserialize_inbound def communicate(cmd, encoding) -> Try: """ Invoke the processes specified by `cmd`. Assumes that the process speaks JSON over stdout. Non-json response are treated as an error. Implementation Note: I don't know why, but `Popen` is like ~5-6x faster than `check_output`. in practice, it means waiting for ~1/10th of a second rather than ~7/10ths of a second. A difference which is pretty weighty when there's a user waiting on the other end. """ try: proc = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=os.environ.copy() ) out, err = proc.communicate() if out and proc.poll() == 0: return Success(deserialize_inbound(out, encoding)) else: return Failure(CalledProcessError(proc.returncode, cmd, output=out, stderr=err)) except JSONDecodeError as e: return Failure(e)