Skip to content

Commit aa337bb

Browse files
authored
fix: argo params issue with char encodings (#2635)
introduce a script for parsing param values from a base64 encoding instead of passing raw values to the command line, in order to get around some encoding issues other JSONType parameter fixes - support both json-strings and proper objects as parameter default values - support json-stringified values in argo event payloads - unify param serialisation between cron and manual triggers
1 parent 59e409b commit aa337bb

File tree

2 files changed

+39
-25
lines changed

2 files changed

+39
-25
lines changed

metaflow/plugins/argo/argo_workflows.py

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,16 @@ def _process_parameters(self):
609609
# the JSON equivalent of None to please argo-workflows. Unfortunately it
610610
# has the side effect of casting the parameter value to string null during
611611
# execution - which needs to be fixed imminently.
612-
if not is_required or default_value is not None:
612+
if default_value is None:
613+
default_value = json.dumps(None)
614+
elif param_type == "JSON":
615+
if not isinstance(default_value, str):
616+
# once to serialize the default value if needed.
617+
default_value = json.dumps(default_value)
618+
# adds outer quotes to param
619+
default_value = json.dumps(default_value)
620+
else:
621+
# Make argo sensors happy
613622
default_value = json.dumps(default_value)
614623

615624
parameters[param.name] = dict(
@@ -941,11 +950,7 @@ def _compile_workflow_template(self):
941950
Arguments().parameters(
942951
[
943952
Parameter(parameter["name"])
944-
.value(
945-
"'%s'" % parameter["value"]
946-
if parameter["type"] == "JSON"
947-
else parameter["value"]
948-
)
953+
.value(parameter["value"])
949954
.description(parameter.get("description"))
950955
# TODO: Better handle IncludeFile in Argo Workflows UI.
951956
for parameter in self.parameters.values()
@@ -2054,7 +2059,7 @@ def _container_templates(self):
20542059
# {{foo.bar['param_name']}}.
20552060
# https://argoproj.github.io/argo-events/tutorials/02-parameterization/
20562061
# http://masterminds.github.io/sprig/strings.html
2057-
"--%s={{workflow.parameters.%s}}"
2062+
"--%s=\\\"$(python -m metaflow.plugins.argo.param_val {{=toBase64(workflow.parameters['%s'])}})\\\""
20582063
% (parameter["name"], parameter["name"])
20592064
for parameter in self.parameters.values()
20602065
]
@@ -3842,37 +3847,27 @@ def _compile_sensor(self):
38423847
# NOTE: We need the conditional logic in order to successfully fall back to the default value
38433848
# when the event payload does not contain a key for a parameter.
38443849
# NOTE: Keys might contain dashes, so use the safer 'get' for fetching the value
3845-
data_template='{{ if (hasKey $.Input.body.payload "%s") }}{{- (get $.Input.body.payload "%s" %s) -}}{{- else -}}{{ (fail "use-default-instead") }}{{- end -}}'
3850+
data_template='{{ if (hasKey $.Input.body.payload "%s") }}%s{{- else -}}{{ (fail "use-default-instead") }}{{- end -}}'
38463851
% (
3847-
v,
38483852
v,
38493853
(
3850-
"| toRawJson | squote"
3854+
'{{- $pv:=(get $.Input.body.payload "%s") -}}{{ if kindIs "string" $pv }}{{- $pv | toRawJson -}}{{- else -}}{{ $pv | toRawJson | toRawJson }}{{- end -}}'
3855+
% v
38513856
if self.parameters[
38523857
parameter_name
38533858
]["type"]
38543859
== "JSON"
3855-
else "| toRawJson"
3860+
else '{{- (get $.Input.body.payload "%s" | toRawJson) -}}'
3861+
% v
38563862
),
38573863
),
38583864
# Unfortunately the sensor needs to
38593865
# record the default values for
38603866
# the parameters - there doesn't seem
38613867
# to be any way for us to skip
3862-
value=(
3863-
json.dumps(
3864-
self.parameters[parameter_name][
3865-
"value"
3866-
]
3867-
)
3868-
if self.parameters[parameter_name][
3869-
"type"
3870-
]
3871-
== "JSON"
3872-
else self.parameters[
3873-
parameter_name
3874-
]["value"]
3875-
),
3868+
value=self.parameters[parameter_name][
3869+
"value"
3870+
],
38763871
)
38773872
.dest(
38783873
# this undocumented (mis?)feature in

metaflow/plugins/argo/param_val.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import sys
2+
import base64
3+
import json
4+
5+
6+
def parse_parameter_value(base64_value):
7+
val = base64.b64decode(base64_value).decode("utf-8")
8+
9+
try:
10+
return json.loads(val)
11+
except json.decoder.JSONDecodeError:
12+
# fallback to using the original value.
13+
return val
14+
15+
16+
if __name__ == "__main__":
17+
base64_val = sys.argv[1]
18+
19+
print(parse_parameter_value(base64_val))

0 commit comments

Comments
 (0)