Пример #1
0
    def check_comparision(self, data, **kwargs):
        """Check comparision for all parameters in schema."""
        for attr, condition in data.items():
            if attr in ["limit", "offset", "sorted_name", "sorted_type", 'lineage_type']:
                continue

            if not isinstance(attr, str):
                raise LineageParamValueError('The search attribute not supported.')

            if attr not in FIELD_MAPPING and not attr.startswith(('metric/', 'user_defined/')):
                raise LineageParamValueError('The search attribute not supported.')

            if not isinstance(condition, dict):
                raise LineageParamTypeError("The search_condition element {} should be dict."
                                            .format(attr))

            for key in condition.keys():
                if key not in ["eq", "lt", "gt", "le", "ge", "in"]:
                    raise LineageParamValueError("The compare condition should be in "
                                                 "('eq', 'lt', 'gt', 'le', 'ge', 'in').")

            if attr.startswith('metric/'):
                if len(attr) == 7:
                    raise LineageParamValueError(
                        'The search attribute not supported.'
                    )
                try:
                    SearchModelConditionParameter.check_param_value_type(condition)
                except ValidationError:
                    raise MindInsightException(
                        error=LineageErrors.LINEAGE_PARAM_METRIC_ERROR,
                        message=LineageErrorMsg.LINEAGE_METRIC_ERROR.value.format(attr)
                    )
        return data
Пример #2
0
def validate_added_info(added_info: dict):
    """
    Check if added_info is valid.

    Args:
        added_info (dict): The added info.

    Raises:
        bool, if added_info is valid, return True.

    """
    added_info_keys = ["tag", "remark"]
    if not set(added_info.keys()).issubset(added_info_keys):
        err_msg = "Keys of added_info must be in {}.".format(added_info_keys)
        raise LineageParamValueError(err_msg)

    for key, value in added_info.items():
        if key == "tag":
            if not isinstance(value, int):
                raise LineageParamValueError("'tag' must be int.")
            # tag should be in [0, 10].
            validate_range("tag", value, min_value=0, max_value=10)
        elif key == "remark":
            if not isinstance(value, str):
                raise LineageParamValueError("'remark' must be str.")
            # length of remark should be in [0, 128].
            validate_range("length of remark",
                           len(value),
                           min_value=0,
                           max_value=128)
Пример #3
0
def validate_condition(search_condition):
    """
    Verify the param in search_condition is valid or not.

    Args:
        search_condition (dict): The search condition.

    Raises:
        LineageParamTypeError: If the type of the param in search_condition is invalid.
        LineageParamValueError: If the value of the param in search_condition is invalid.
    """
    if not isinstance(search_condition, dict):
        log.error("Invalid search_condition type, it should be dict.")
        raise LineageParamTypeError("Invalid search_condition type, "
                                    "it should be dict.")

    if "limit" in search_condition:
        if isinstance(search_condition.get("limit"), bool) \
                or not isinstance(search_condition.get("limit"), int):
            log.error("The limit must be int.")
            raise LineageParamTypeError("The limit must be int.")

    if "offset" in search_condition:
        if isinstance(search_condition.get("offset"), bool) \
                or not isinstance(search_condition.get("offset"), int):
            log.error("The offset must be int.")
            raise LineageParamTypeError("The offset must be int.")

    if "sorted_name" in search_condition:
        sorted_name = search_condition.get("sorted_name")
        err_msg = "The sorted_name must be in {} or start with " \
                  "`metric/` or `user_defined/`.".format(list(FIELD_MAPPING.keys()))
        if not isinstance(sorted_name, str):
            log.error(err_msg)
            raise LineageParamValueError(err_msg)
        if not (sorted_name in FIELD_MAPPING or
                (sorted_name.startswith('metric/')
                 and len(sorted_name) > len('metric/')) or
                (sorted_name.startswith('user_defined/')
                 and len(sorted_name) > len('user_defined/'))
                or sorted_name in ['tag']):
            log.error(err_msg)
            raise LineageParamValueError(err_msg)

    sorted_type_param = ['ascending', 'descending', None]
    if "sorted_type" in search_condition:
        if "sorted_name" not in search_condition:
            log.error("The sorted_name have to exist when sorted_type exists.")
            raise LineageParamValueError(
                "The sorted_name have to exist when sorted_type exists.")

        if search_condition.get("sorted_type") not in sorted_type_param:
            err_msg = "The sorted_type must be ascending or descending."
            log.error(err_msg)
            raise LineageParamValueError(err_msg)
Пример #4
0
def validate_path(summary_path):
    """
    Verify the summary path is valid or not.

    Args:
        summary_path (str): The summary path which is a dir.

    Raises:
        LineageParamValueError: If the input param value is invalid.
        LineageDirNotExistError: If the summary path is invalid.
    """
    try:
        summary_path = safe_normalize_path(summary_path,
                                           "summary_path",
                                           None,
                                           check_absolute_path=True)
    except ValidationError:
        log.error("The summary path is invalid.")
        raise LineageParamValueError("The summary path is invalid.")
    if not os.path.isdir(summary_path):
        log.error("The summary path does not exist or is not a dir.")
        raise LineageDirNotExistError(
            "The summary path does not exist or is not a dir.")

    return summary_path
Пример #5
0
def validate_filter_key(keys):
    """
    Verify the keys of filtering is valid or not.

    Args:
        keys (list): The keys to get the relative lineage info.

    Raises:
        LineageParamTypeError: If keys is not list.
        LineageParamValueError: If the value of keys is invalid.
    """
    filter_keys = [
        'metric', 'hyper_parameters', 'algorithm', 'train_dataset', 'model',
        'valid_dataset', 'dataset_graph'
    ]

    if not isinstance(keys, list):
        log.error("Keys must be list.")
        raise LineageParamTypeError("Keys must be list.")

    for element in keys:
        if not isinstance(element, str):
            log.error("Element of keys must be str.")
            raise LineageParamTypeError("Element of keys must be str.")

    if not set(keys).issubset(filter_keys):
        err_msg = "Keys must be in {}.".format(filter_keys)
        log.error(err_msg)
        raise LineageParamValueError(err_msg)
Пример #6
0
 def test_failed_to_convert_path(self, mock_convert, *args):
     """Test filter_summary_lineage with invalid invalid param."""
     mock_convert.side_effect = LineageParamValueError('invalid path')
     args[0].return_value = None
     self.assertRaisesRegex(LineageParamSummaryPathError, 'invalid path',
                            filter_summary_lineage, '/path/to/summary/dir',
                            {})
Пример #7
0
def validate_range(name, value, min_value, max_value):
    """
    Check if value is in [min_value, max_value].

    Args:
        name (str): Value name.
        value (Union[int, float]): Value to be check.
        min_value (Union[int, float]): Min value.
        max_value (Union[int, float]): Max value.

    Raises:
        LineageParamValueError, if value type is invalid or value is out of [min_value, max_value].

    """
    if not isinstance(value, (int, float)):
        raise LineageParamValueError("Value should be int or float.")

    if value < min_value or value > max_value:
        raise LineageParamValueError("The %s should in [%d, %d]." % (name, min_value, max_value))
Пример #8
0
def _convert_relative_path_to_abspath(summary_base_dir, search_condition):
    """
    Convert relative path to absolute path.

    Args:
        summary_base_dir (str): The summary base directory.
        search_condition (dict): The search condition.

    Returns:
        dict, the updated search_condition.

    Raises:
        LineageParamValueError: If the value of input_name is invalid.
    """
    if ("summary_dir" not in search_condition) or (
            not search_condition.get("summary_dir")):
        return search_condition

    summary_dir_condition = search_condition.get("summary_dir")
    if not set(summary_dir_condition.keys()).issubset(['in', 'eq']):
        raise LineageParamValueError("Invalid operation of summary dir.")

    if 'in' in summary_dir_condition:
        summary_paths = []
        for summary_dir in summary_dir_condition.get('in'):
            if summary_dir.startswith('./'):
                abs_dir = os.path.join(summary_base_dir, summary_dir[2:])
                abs_dir = validate_path(abs_dir)
            else:
                abs_dir = validate_path(summary_dir)
            summary_paths.append(abs_dir)
        search_condition.get('summary_dir')['in'] = summary_paths

    if 'eq' in summary_dir_condition:
        summary_dir = summary_dir_condition.get('eq')
        if summary_dir.startswith('./'):
            abs_dir = os.path.join(summary_base_dir, summary_dir[2:])
            abs_dir = validate_path(abs_dir)
        else:
            abs_dir = validate_path(summary_dir)
        search_condition.get('summary_dir')['eq'] = abs_dir

    return search_condition
Пример #9
0
def get_relative_path(path, base_path):
    """
    Get relative path based on base_path.

    Args:
        path (str): absolute path.
        base_path: absolute base path.

    Returns:
        str, relative path based on base_path.

    """
    try:
        r_path = str(Path(path).relative_to(Path(base_path)))
    except ValueError:
        raise LineageParamValueError("The path %r does not start with %r." % (path, base_path))

    if r_path == ".":
        r_path = ""
    return os.path.join("./", r_path)
Пример #10
0
def validate_str_by_regular(target, reg=None, flag=re.ASCII):
    """
    Validate string by given regular.

    Args:
        target: target string.
        reg: pattern.
        flag: pattern mode.

    Raises:
        LineageParamValueError, if string not match given pattern.

    Returns:
        bool, if target matches pattern, return True.

    """
    if reg is None:
        reg = _name_re
    if re.match(reg, target, flag) is None:
        raise LineageParamValueError("'{}' is illegal, it should be match "
                                     "regular'{}' by flags'{}'".format(target, reg, flag))
    return True
Пример #11
0
def validate_user_defined_info(user_defined_info):
    """
    Validate user defined info, delete the item if its key is in lineage.

    Args:
        user_defined_info (dict): The user defined info.

    Raises:
        LineageParamTypeError: If the type of parameters is invalid.
        LineageParamValueError: If user defined keys have been defined in lineage.

    """
    if not isinstance(user_defined_info, dict):
        log.error("Invalid user defined info. It should be a dict.")
        raise LineageParamTypeError(
            "Invalid user defined info. It should be dict.")
    for key, value in user_defined_info.items():
        if not isinstance(key, str):
            error_msg = "Dict key type {} is not supported in user defined info." \
                        "Only str is permitted now.".format(type(key))
            log.error(error_msg)
            raise LineageParamTypeError(error_msg)
        if not isinstance(value, (int, str, float)):
            error_msg = "Dict value type {} is not supported in user defined info." \
                        "Only str, int and float are permitted now.".format(type(value))
            log.error(error_msg)
            raise LineageParamTypeError(error_msg)

    field_map = set(FIELD_MAPPING.keys())
    user_defined_keys = set(user_defined_info.keys())
    insertion = list(field_map & user_defined_keys)

    if insertion:
        for key in insertion:
            user_defined_info.pop(key)
        raise LineageParamValueError(
            "There are some keys have defined in lineage. "
            "Duplicated key(s): %s. " % insertion)
Пример #12
0
    def test_validate_search_model_condition(self):
        """Test the mothod of validate_search_model_condition."""
        condition = {'summary_dir': 'xxx'}
        self.assertRaisesRegex(
            LineageParamTypeError,
            'The search_condition element summary_dir should be dict.',
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'xxx': 'xxx'}
        self.assertRaisesRegex(LineageParamValueError,
                               'The search attribute not supported.',
                               validate_search_model_condition,
                               SearchModelConditionParameter, condition)

        condition = {'learning_rate': {'xxx': 'xxx'}}
        self.assertRaisesRegex(LineageParamValueError,
                               "The compare condition should be in",
                               validate_search_model_condition,
                               SearchModelConditionParameter, condition)

        condition = {"offset": 100001}
        self.assertRaisesRegex(MindInsightException,
                               "Invalid input offset. 0 <= offset <= 100000",
                               validate_search_model_condition,
                               SearchModelConditionParameter, condition)

        condition = {'summary_dir': {'eq': 111}, 'limit': 10}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter summary_dir is invalid. It should be a dict and the value should be a string",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'learning_rate': {'in': 1.0}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter learning_rate is invalid. It should be a dict and the value should be a float or a integer",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'learning_rate': {'lt': True}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter learning_rate is invalid. It should be a dict and the value should be a float or a integer",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'learning_rate': {'gt': [1.0]}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter learning_rate is invalid. It should be a dict and the value should be a float or a integer",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'loss_function': {'ge': 1}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter loss_function is invalid. It should be a dict and the value should be a string",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'train_dataset_count': {'in': 2}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter train_dataset_count is invalid. It should be a dict "
            "and the value should be a integer between 0",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'network': {'le': 2}, 'optimizer': {'eq': 'xxx'}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter network is invalid. It should be a dict and the value should be a string",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {
            'batch_size': {
                'lt': 2,
                'gt': 'xxx'
            },
            'model_size': {
                'eq': 222
            }
        }
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter batch_size is invalid. It should be a non-negative integer.",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'test_dataset_count': {'lt': -2}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter test_dataset_count is invalid. It should be a dict "
            "and the value should be a integer between 0",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {'epoch': {'lt': False}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter epoch is invalid. It should be a positive integer.",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {"learning_rate": {"ge": ""}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter learning_rate is invalid. It should be a dict and the value should be a float or a integer",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {"train_dataset_count": {"ge": 8.0}}
        self.assertRaisesRegex(
            MindInsightException,
            "The parameter train_dataset_count is invalid. It should be a dict "
            "and the value should be a integer between 0",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)

        condition = {1: {"ge": 8.0}}
        self.assertRaisesRegex(LineageParamValueError,
                               "The search attribute not supported.",
                               validate_search_model_condition,
                               SearchModelConditionParameter, condition)

        condition = {'metric_': {"ge": 8.0}}
        LineageParamValueError('The search attribute not supported.')
        self.assertRaisesRegex(LineageParamValueError,
                               "The search attribute not supported.",
                               validate_search_model_condition,
                               SearchModelConditionParameter, condition)

        condition = {'metric_attribute': {'ge': 'xxx'}}
        self.assertRaisesRegex(
            MindInsightException, "The parameter metric_attribute is invalid. "
            "It should be a dict and the value should be a float or a integer",
            validate_search_model_condition, SearchModelConditionParameter,
            condition)