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

"""
Because Gooey communicates with the host program
over stdin/out, we have to be able to differentiate what's
coming from gooey and structured, versus what is arbitrary
junk coming from the host's own logging.
To do this, we just prefix all written by gooey with the
literal string 'gooey::'. This lets us dig through all the
noisy stdout to find just the structured Gooey data we're
after.
"""
import json
from base64 import b64decode
from typing import Dict, Any
from gooey.python_bindings.schema import validate_public_state
from gooey.python_bindings.types import PublicGooeyState
prefix = 'gooey::'
def serialize_outbound(out: PublicGooeyState):
"""
Attaches a prefix to whatever is about to be written
to stdout so that we can differentiate it in the
sea of other stdout writes
"""
return prefix + json.dumps(out)
def deserialize_inbound(stdout: bytes, encoding):
"""
Deserializes the incoming stdout payload after
finding the relevant sections give the gooey prefix.
e.g.
std='foo\nbar\nstarting run\ngooey::{active_form: [...]}\n'
=> {active_form: [...]}
"""
data = json.loads(stdout.decode(encoding).split(prefix)[-1])
return validate_public_state(data)
def decode_payload(x):
"""
To avoid quoting shenanigans, the json state sent from
Gooey is b64ecoded for ease of CLI transfer. Argparse will
usually barf when trying to parse json directly
"""
return json.loads(b64decode(x))