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.

50 lines
1.4 KiB

2 years ago
  1. """
  2. Because Gooey communicates with the host program
  3. over stdin/out, we have to be able to differentiate what's
  4. coming from gooey and structured, versus what is arbitrary
  5. junk coming from the host's own logging.
  6. To do this, we just prefix all written by gooey with the
  7. literal string 'gooey::'. This lets us dig through all the
  8. noisy stdout to find just the structured Gooey data we're
  9. after.
  10. """
  11. import json
  12. from base64 import b64decode
  13. from typing import Dict, Any
  14. from gooey.python_bindings.schema import validate_public_state
  15. from gooey.python_bindings.types import PublicGooeyState
  16. prefix = 'gooey::'
  17. def serialize_outbound(out: PublicGooeyState):
  18. """
  19. Attaches a prefix to whatever is about to be written
  20. to stdout so that we can differentiate it in the
  21. sea of other stdout writes
  22. """
  23. return prefix + json.dumps(out)
  24. def deserialize_inbound(stdout: bytes, encoding):
  25. """
  26. Deserializes the incoming stdout payload after
  27. finding the relevant sections give the gooey prefix.
  28. e.g.
  29. std='foo\nbar\nstarting run\ngooey::{active_form: [...]}\n'
  30. => {active_form: [...]}
  31. """
  32. data = json.loads(stdout.decode(encoding).split(prefix)[-1])
  33. return validate_public_state(data)
  34. def decode_payload(x):
  35. """
  36. To avoid quoting shenanigans, the json state sent from
  37. Gooey is b64ecoded for ease of CLI transfer. Argparse will
  38. usually barf when trying to parse json directly
  39. """
  40. return json.loads(b64decode(x))