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.

38 lines
1.3 KiB

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