lib.util.run_curl(): Add decode parameter

run_curl() has no clear API of whether or not the return values should
be decoded. It has parse_json, which should imply decoding, but there's
no way to specify that explicitly. Moreover, when it tries to decode, it
decodes on the coroutine returned from run_cmd(), not the awaited
coroutine return value.

Add a decode parameter, defaulting to False, change the parse_json
parameter's default from True to False, and fix the run_cmd() return
value evaluation.

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-04-07 13:04:11 +02:00
commit f18575a267

View file

@ -40,25 +40,30 @@ async def run_cmd(*args, ec: ExecContext|None=None, verbose: bool|None=None, **k
ec = Local(verbose_default=verbose)
return await ec.run(verbose=verbose, *args, **kwargs)
async def run_curl(args: list[str], parse_json: bool=True, wd=None, throw=None, verbose=None, cmd_input=None, ec: ExecContext|None=None) -> dict|str: # export
async def run_curl(args: list[str], parse_json: bool=False, wd=None, throw=None, verbose=None, cmd_input=None, ec: ExecContext|None=None, decode=False) -> dict|str: # export
if verbose is None:
verbose = False if ec is None else ec.verbose_default
cmd = ['curl']
if not verbose:
cmd.append('-s')
cmd.extend(args)
ret, stderr, status = await run_cmd(cmd, wd=wd, throw=throw, verbose=verbose, cmd_input=cmd_input, ec=ec).decode()
if parse_json:
decode = True
output = await run_cmd(cmd, wd=wd, throw=throw, verbose=verbose, cmd_input=cmd_input, ec=ec)
stdout, stderr, status = output.decode() if decode else output
if not parse_json:
ret = stdout
else:
try:
ret = json.loads(ret)
ret = json.loads(stdout)
except Exception as e:
size = 'unknown number of'
try:
size = len(ret)
size = len(stdout)
except:
pass
log(ERR, f'Failed to parse {size} bytes output of command '
+ f'>{pretty_cmd(cmd, wd)}< ({str(e)}): "{ret}"', file=sys.stderr)
+ f'>{pretty_cmd(cmd, wd)}< ({str(e)}): "{stdout}"', file=sys.stderr)
raise
return ret, stderr, status