def expand_value(value, arguments, parameters): """Test whether the string is a reference to a template parameter and (if True) replace the value with the given argument or default value. In the current implementation template parameters are referenced using $[[..]] syntax. Parameters ---------- value: string String value in the workflow specification for a template parameter arguments: dict Dictionary that associates template parameter identifiers with argument values parameters: flowserv.model.template.parameter.ParameterIndex Dictionary of parameter declarations Returns ------- any Raises ------ flowserv.error.MissingArgumentError """ if isinstance(value, str) and value.startswith('$[[') and value.endswith(']]'): # Strip expression of parameter reference syntax. expr = value[3:-2] pos = expr.find('?') if pos == -1: para = parameters[expr] # If arguments contains a value for the variable we return the # associated value from the dictionary. Otherwise, the default # value is returned or and error is raised if no default value # is defined for the parameter. if expr in arguments: return arguments[expr] elif para.default is not None: # Return the parameter default value. return para.default raise err.MissingArgumentError(para.name) # Extract the variable name and the conditional return values. var = expr[:pos].strip() expr = expr[pos + 1:].strip() pos = expr.find(':') if pos == -1: eval_true = expr eval_false = None else: eval_true = expr[:pos].strip() eval_false = expr[pos + 1:].strip() if var not in arguments: raise err.MissingArgumentError(var) if str(arguments[var]).lower() == 'true': return eval_true else: return eval_false return value
def replace_ref(match): """Function to replace references to template parameters in a given string. Used as callback function by the regular expression substitute method. Parameters ---------- match: re.MatchObject Regular expression match object. Returns ------- string """ ref = match.group() # Strip expression of parameter reference syntax. expr = ref[3:-2] pos = expr.find('?') if pos == -1: para = parameters[expr] # If arguments contains a value for the variable we return the # associated value from the dictionary. Otherwise, the default # value is returned or and error is raised if no default value # is defined for the parameter. if expr in arguments: return str(arguments[expr]) elif para.default is not None: # Return the parameter default value. return str(para.default) raise err.MissingArgumentError(para.name) # Extract the variable name and the conditional return values. var = expr[:pos].strip() expr = expr[pos + 1:].strip() pos = expr.find(':') if pos == -1: eval_true = expr eval_false = None else: eval_true = expr[:pos].strip() eval_false = expr[pos + 1:].strip() if var not in arguments: raise err.MissingArgumentError(var) if str(arguments[var]).lower() == 'true': return eval_true else: return eval_false
def get_value(value, arguments): """Get the result value from evaluating a parameter reference expression. Expects a value that satisfies the is_parameter() predicate. If the given expression is unconditional, e.g., $[[name]], the parameter name is the returned result. If the expression is conditional, e.g., $[[name ? x : y]] the argument value for parameter 'name' is tested for being Boolean True or False. Depending on the outcome of the evaluation either x or y are returned. Note that nested conditional expressions are currently not supported. Parameters ---------- value: string Parameter reference string that satisifes the is_parameter() predicate. arguments: dict Dictionary of user-provided argument values for template arguments. Returns ------- string Raises ------ flowserv.error.MissingArgumentError """ # Strip expression of parameter reference syntax. expr = value[3:-2] pos = expr.find('?') if pos == -1: # Return immediately if this is an unconditional expression. return expr # Extract the variable name and the conditional return values. var = expr[:pos].strip() expr = expr[pos + 1:].strip() pos = expr.find(':') if pos == -1: eval_true = expr eval_false = None else: eval_true = expr[:pos].strip() eval_false = expr[pos + 1:].strip() if var not in arguments: raise err.MissingArgumentError(var) if str(arguments[var]).lower() == 'true': return eval_true else: return eval_false
def validate_arguments(self, arguments): """Ensure that the workflow can be instantiated using the given set of arguments. Raises an error if there are template parameters for which the argument set does not provide a value and that do not have a default value. Parameters ---------- arguments: dict Dictionary of argument values for parameters in the template Raises ------ flowserv.error.MissingArgumentError """ for para in self.parameters.values(): if para.required and para.default is None: if para.name not in arguments: raise err.MissingArgumentError(para.name)