Commit 67d7dbb9 authored by Floreal Cabanettes's avatar Floreal Cabanettes
Browse files

Remove Unique/UniqueAll rules + Add FilesUnique rule + add check of type...

Remove Unique/UniqueAll rules + Add FilesUnique rule + add check of type function on rules + add specific exceptions
parent 7d08c769
......@@ -28,6 +28,7 @@ except ImportError:
from jflow.workflows_manager import WorkflowsManager
from jflow.workflow import Workflow
import jflow.utils as utils
from jflow.exceptions import RuleException, RuleIgnore
class JflowArgumentParser (argparse.ArgumentParser):
......@@ -148,9 +149,12 @@ if __name__ == '__main__':
try:
workflow = wfmanager.get_workflow_by_class(args["cmd_object"])
workflow.check_parameters_rules(args)
wfmanager.run_workflow(args["cmd_object"], args)
except Exception as e:
except RuleException as e:
sub_parser.error(e)
except RuleIgnore:
pass
wfmanager.run_workflow(args["cmd_object"], args)
elif args["cmd_object"] == "rerun":
wfmanager.rerun_workflow(args["workflow_id"])
elif args["cmd_object"] == "reset":
......
class RuleException (Exception):
pass
class RuleIgnore (Exception):
pass
......@@ -19,7 +19,9 @@ import re
from abc import ABC, abstractmethod
from jflow.parameter import InputFile, InputFileList, InputDirectory, MultiParameter, MultiParameterList
from jflow.parameter import *
from jflow.exceptions import RuleException, RuleIgnore
#################
......@@ -28,12 +30,11 @@ from jflow.parameter import InputFile, InputFileList, InputDirectory, MultiParam
class SimpleRule (ABC):
def __init__(self, user_args, wf_instance, src_arg, nb_rows, all_files=None):
def __init__(self, user_args, wf_instance, src_arg, nb_rows):
self.user_args = user_args
self.wf_instance = wf_instance
self.parameter_name = src_arg
self.parameter_value = user_args[src_arg]
self.all_files = all_files
self.nb_rows = nb_rows
if ">" not in src_arg:
self.wf_parameter = getattr(wf_instance, src_arg)
......@@ -47,9 +48,29 @@ class SimpleRule (ABC):
self.is_directory = isinstance(self.wf_parameter, InputDirectory)
self.is_file_or_directory = self.is_file or self.is_directory
def check_allowed_types(self, allowed_types):
if self.parameter_name.find(">") == -1:
parameter_obj = getattr(self.wf_instance, self.parameter_name)
else:
parts = self.parameter_name.split(">")
parent_name = parts[0]
sub_param_name = parts[1]
parent_obj = getattr(self.wf_instance, parent_name)
parameter_obj = parent_obj.get_sub_parameters_by_name()[sub_param_name]
good_type = False
for type_param in allowed_types:
if isinstance(parameter_obj, type_param):
good_type = True
break
if not good_type:
self.warning("Rule " + type(self).__name__ + " ignored on parameter " + self.parameter_name + ": rule not "
"allowed here")
raise RuleIgnore()
@staticmethod
def error(message):
raise Exception(message)
raise RuleException(message)
@staticmethod
def warning(message):
......@@ -61,8 +82,8 @@ class SimpleRule (ABC):
class LinkRule (SimpleRule):
def __init__(self, user_args, wf_instance, src_arg, targets_args, nb_rows, all_files=None):
SimpleRule.__init__(self, user_args, wf_instance, src_arg, nb_rows, all_files)
def __init__(self, user_args, wf_instance, src_arg, targets_args, nb_rows):
SimpleRule.__init__(self, user_args, wf_instance, src_arg, nb_rows)
self.targets_args = targets_args
@abstractmethod
......@@ -71,8 +92,8 @@ class LinkRule (SimpleRule):
class ConditionalRule(SimpleRule):
def __init__(self, user_args, wf_instance, src_arg, conditions, which, nb_rows, all_files=None):
SimpleRule.__init__(self, user_args, wf_instance, src_arg, nb_rows, all_files)
def __init__(self, user_args, wf_instance, src_arg, conditions, which, nb_rows):
SimpleRule.__init__(self, user_args, wf_instance, src_arg, nb_rows)
self.conditions = conditions
# Test condition is raised:
......
......@@ -30,6 +30,8 @@ import logging
from argparse import ArgumentTypeError
from jflow.exceptions import RuleException, RuleIgnore
from collections import OrderedDict
from .workflows_manager import WorkflowsManager
......@@ -324,8 +326,10 @@ class JFlowServer (object):
workflow = self.wfmanager.get_workflow_by_class(kwargs_modified["workflow_class"])
try:
workflow.check_parameters_rules(kwargs_modified)
except Exception as e:
except RuleException as e:
return {"status": 1, "content": str(e)}
except RuleIgnore:
pass
return {"status": 0}
@cherrypy.expose
......
......@@ -1266,18 +1266,17 @@ class Workflow(threading.Thread):
parameters_used[parameter.name] = user_params[parameter.name] if parameter.name in user_params else None
if parameter.rules is not None:
rules[parameter.name] = parameter.rules.split(";")
if isinstance(parameter, InputFile) and parameter.name in user_params:
all_files.append(user_params[parameter.name])
elif isinstance(parameter, InputFileList) and parameter.name in user_params:
all_files += user_params[parameter.name]
if isinstance(parameter, InputFileList) and parameter.name in user_params:
if len(set(user_params[parameter.name])) < len(user_params[parameter.name]):
raise Exception("Error for parameter " + parameter.name + ": some files are duplicated")
# Check rules:
for src_arg, arg_rules in rules.items():
for arg_rule in arg_rules:
if arg_rule != "":
self.check_parameter_rule(arg_rule, src_arg, parameters_used, all_files, nb_rows)
self.check_parameter_rule(arg_rule, src_arg, parameters_used, nb_rows)
def check_parameter_rule(self, rule: str, src_arg: str, user_args: dict, all_files: list, nb_rows: dict):
def check_parameter_rule(self, rule: str, src_arg: str, user_args: dict, nb_rows: dict):
"""
Check a parameter rule
@param rule: string describing the rule
......@@ -1319,11 +1318,12 @@ class Workflow(threading.Thread):
# Launch validator:
if issubclass(validator_class, j_rules.ConditionalRule): # Check the rule is the same special rule
validator = validator_class(user_args, self, src_arg, conditions, which, nb_rows, all_files)
validator = validator_class(user_args, self, src_arg, conditions, which, nb_rows)
validator.check()
else:
raise Exception("Rule is not a conditional link rule: " + name)
elif src_arg in user_args and user_args[src_arg] is not None and user_args[src_arg]:
elif (src_arg in user_args and user_args[src_arg] is not None and user_args[src_arg]) or \
(isinstance(getattr(self, src_arg), MultiParameterList)):
is_link_rule = re.match(link_rule, rule) # Check the second special rule
if is_link_rule:
# Check this special rule:
......@@ -1340,7 +1340,7 @@ class Workflow(threading.Thread):
# Launch validator
if issubclass(validator_class, j_rules.LinkRule): # Check the rule is the same special rule
validator = validator_class(user_args, self, src_arg, targets, nb_rows, all_files)
validator = validator_class(user_args, self, src_arg, targets, nb_rows)
validator.check()
else:
raise Exception("Rule is not a link rule: " + name)
......@@ -1357,7 +1357,7 @@ class Workflow(threading.Thread):
# Launch validator:
if issubclass(validator_class, j_rules.SimpleRule): # Check it's a simple rule
validator = validator_class(user_args, self, src_arg, nb_rows, all_files)
validator = validator_class(user_args, self, src_arg, nb_rows)
validator.check()
else:
raise Exception("Rule is not a simple rule: " + name)
......@@ -265,7 +265,7 @@
var t_obj = $("#" + target);
var current_rules = t_obj.rules();
if ("required" in current_rules && current_rules["required"] == true
if ("required" in current_rules && current_rules["required"] === true
&& t_obj.attr("initial_requirement") === undefined) {
t_obj.attr("initial_requirement", "TRUE");
}
......@@ -288,7 +288,7 @@
var target = targets[i];
var t_obj = $("#" + target);
var current_rules = t_obj.rules();
if ("required" in current_rules && current_rules["required"] == true) {
if ("required" in current_rules && current_rules["required"] === true) {
if ((t_obj.attr("initial_requirement") === undefined || t_obj.attr("initial_requirement") == "FALSE")
&& (!_get_param_keep_required(target))) {
t_obj.rules("remove", "required");
......
......@@ -16,40 +16,29 @@
#
from jflow.rules import SimpleRule, LinkRule, ConditionalRule
from jflow.parameter import *
# Define your rules check below
class Unique(SimpleRule):
class FilesUnique(SimpleRule):
"""
The file given in a file list parameter must be given only one time in the list
Files into a MultipleParameterList must be unique
"""
def check(self):
if self.is_file_list:
for file in self.parameter_value:
if self.parameter_value.count(file) > 1:
self.error("the file \"" + file + "\" in parameter \"" + self.parameter_name + "\" is duplicated")
else:
self.warning("rule Unique is ignored: " + self.parameter_name + " is not an input file list")
class UniqueAll(SimpleRule):
"""
The file given for one parameter must be given only one time for it and for all files given in any parameter of the
workflow
"""
def check(self):
if self.is_file:
files = self.parameter_value if type(self.parameter_value) == list else [self.parameter_value]
for file in files:
if self.all_files.count(file) > 1:
self.error("the file \"" + file + "\" from parameter \"" + self.parameter_name + "\" is given "
"several times (on this or another argument)")
else:
self.warning("rule UniqueAll is ignored: " + self.parameter_name +
" is not an input file or input file list")
self.check_allowed_types([MultiParameterList])
all_files = []
param_obj = getattr(self.wf_instance, self.parameter_name)
sub_parameters = param_obj.get_sub_parameters_by_name()
for arg, value in self.user_args.items():
if arg.startswith(self.parameter_name + ">"):
sub_parameter = arg.replace(self.parameter_name + ">", "").replace("-", "_")
sub_parameter_obj = sub_parameters[sub_parameter][0]
if isinstance(sub_parameter_obj, InputFile) or isinstance(sub_parameter_obj, InputDirectory):
all_files.append(value[0])
if len(set(all_files)) < len(all_files):
self.error("Some files into " + self.parameter_name + " are given several times")
class FullOrEmpty(SimpleRule):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment