You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

41 lines
1.3 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. """
  2. Util for talking to the client program in order to retrieve
  3. dynamic defaults for the UI
  4. """
  5. import subprocess
  6. from json import JSONDecodeError
  7. from subprocess import CalledProcessError
  8. import os
  9. from gooey.python_bindings.types import Try, Success, Failure
  10. from gooey.python_bindings.coms import deserialize_inbound
  11. def communicate(cmd, encoding) -> Try:
  12. """
  13. Invoke the processes specified by `cmd`.
  14. Assumes that the process speaks JSON over stdout. Non-json response
  15. are treated as an error.
  16. Implementation Note: I don't know why, but `Popen` is like ~5-6x faster
  17. than `check_output`. in practice, it means waiting for ~1/10th
  18. of a second rather than ~7/10ths of a second. A
  19. difference which is pretty weighty when there's a
  20. user waiting on the other end.
  21. """
  22. try:
  23. proc = subprocess.Popen(
  24. cmd,
  25. stdout=subprocess.PIPE,
  26. stderr=subprocess.PIPE,
  27. env=os.environ.copy()
  28. )
  29. out, err = proc.communicate()
  30. if out and proc.poll() == 0:
  31. return Success(deserialize_inbound(out, encoding))
  32. else:
  33. return Failure(CalledProcessError(proc.returncode, cmd, output=out, stderr=err))
  34. except JSONDecodeError as e:
  35. return Failure(e)