Exemplo n.º 1
0
    def __init__(self, data_filter=None, do_validate=False):
        """Creates a v6 data filter JSON object from the given dictionary

        :param data_filter: The data filter JSON dict
        :type data_filter: dict
        :param do_validate: Whether to perform validation on the JSON schema
        :type do_validate: bool

        :raises :class:`data.filter.exceptions.InvalidDataFilter`: If the given data filter is invalid
        """

        if not data_filter:
            data_filter = {'filters': [], 'all': True}
        self._data_filter = data_filter

        if 'version' not in self._data_filter:
            self._data_filter['version'] = SCHEMA_VERSION

        if self._data_filter['version'] not in SCHEMA_VERSIONS:
            msg = '%s is an unsupported version number'
            raise InvalidDataFilter('INVALID_VERSION',
                                    msg % self._data_filter['version'])

        if 'all' not in self._data_filter:
            self._data_filter['all'] = True

        if 'filters' not in self._data_filter:
            self._data_filter['filters'] = []

        try:
            if do_validate:
                validate(self._data_filter, DATA_FILTER_SCHEMA)
                for f in data_filter['filters']:
                    DataFilter.validate_filter(f)
        except ValidationError as ex:
            raise InvalidDataFilter('INVALID_DATA_FILTER',
                                    'Invalid data filter: %s' % unicode(ex))
Exemplo n.º 2
0
    def __init__(self, data_filter=None, do_validate=False):
        """Creates a v6 data filter JSON object from the given dictionary

        :param data_filter: The data filter JSON dict
        :type data_filter: dict
        :param do_validate: Whether to perform validation on the JSON schema
        :type do_validate: bool

        :raises :class:`data.filter.exceptions.InvalidDataFilter`: If the given data filter is invalid
        """

        if not data_filter:
            data_filter = {}
        self._data_filter = data_filter

        if 'version' not in self._data_filter:
            self._data_filter['version'] = SCHEMA_VERSION

        try:
            if do_validate:
                validate(self._data_filter, DATA_FILTER_SCHEMA)
        except ValidationError as ex:
            raise InvalidDataFilter('INVALID_DATA_FILTER', 'Invalid data filter: %s' % unicode(ex))
Exemplo n.º 3
0
    def validate_filter(filter_dict):
        """Validates a data filter dictionary

        :param filter_dict: data filter to validate
        :type filter_dict: dict

        :raises :class:`recipe.definition.exceptions.InvalidDataFilter`: If the filter is invalid

        :returns: Validated filter if the tests pass
        :rtype: dict
        """

        if 'name' not in filter_dict:
            raise InvalidDataFilter('MISSING_NAME', 'Missing name for filter')

        name = filter_dict['name']
        if 'type' not in filter_dict:
            raise InvalidDataFilter('MISSING_TYPE',
                                    'Missing type for \'%s\'' % name)

        if 'condition' not in filter_dict:
            raise InvalidDataFilter('MISSING_CONDITION',
                                    'Missing condition for \'%s\'' % name)

        if 'values' not in filter_dict:
            raise InvalidDataFilter('MISSING_VALUES',
                                    'Missing values for \'%s\'' % name)

        filter_type = filter_dict['type']
        condition = filter_dict['condition']
        values = filter_dict['values']

        if condition not in ALL_CONDITIONS:
            raise InvalidDataFilter(
                'INVALID_CONDITION',
                'Invalid condition \'%s\' for \'%s\'. Valid conditions are: %s'
                % (condition, name, ALL_CONDITIONS))

        if filter_type in STRING_TYPES and condition not in STRING_CONDITIONS:
            raise InvalidDataFilter(
                'INVALID_CONDITION',
                'Invalid condition \'%s\' for \'%s\'. Valid conditions are: %s'
                % (condition, name, STRING_CONDITIONS))

        if filter_type in NUMBER_TYPES and condition not in NUMBER_CONDITIONS:
            raise InvalidDataFilter(
                'INVALID_CONDITION',
                'Invalid condition \'%s\' for \'%s\'. Valid conditions are: %s'
                % (condition, name, NUMBER_CONDITIONS))

        if filter_type in BOOL_TYPES and condition not in BOOL_CONDITIONS:
            raise InvalidDataFilter(
                'INVALID_CONDITION',
                'Invalid condition \'%s\' for \'%s\'. Valid conditions are: %s'
                % (condition, name, BOOL_CONDITIONS))

        if filter_type in OBJECT_TYPES and condition not in OBJECT_CONDITIONS:
            if 'fields' not in filter_dict or not filter_dict['fields']:
                msg = 'Object %s does not have object condition (%s) and fields property is not set'
                raise InvalidDataFilter('INVALID_CONDITION',
                                        msg % (name, OBJECT_CONDITIONS))

        if 'fields' in filter_dict:
            if len(filter_dict['fields']) != len(values):
                raise InvalidDataFilter(
                    'INVALID_FIELDS',
                    'Fields property must be same length as values')

        if filter_type not in STRING_TYPES and filter_type not in NUMBER_TYPES and filter_type not in BOOL_TYPES and filter_type not in OBJECT_TYPES:
            raise InvalidDataFilter('INVALID_TYPE',
                                    'No valid conditions for this type')

        filter_values = []
        if filter_type == 'number':
            for value in values:
                try:
                    filter_values.append(float(value))
                except ValueError:
                    raise InvalidDataFilter(
                        'VALUE_ERROR',
                        'Expected float for \'%s\', found %s' % (name, value))
        elif filter_type == 'integer':
            for value in values:
                try:
                    filter_values.append(int(value))
                except ValueError:
                    raise InvalidDataFilter(
                        'VALUE_ERROR',
                        'Expected int for \'%s\', found %s' % (name, value))
        else:
            filter_values.extend(values)

        ret_val = copy.deepcopy(filter_dict)
        ret_val['values'] = filter_values
        return ret_val
Exemplo n.º 4
0
    def validate(self, interface):
        """Validates this data filter against the given interface

        :param interface: The interface describing the data that will be passed to the filter
        :type interface: :class:`data.interface.interface.Interface`
        :returns: A list of warnings discovered during validation
        :rtype: :func:`list`

        :raises :class:`data.filter.exceptions.InvalidDataFilter`: If the data filter is invalid
        """

        warnings = []
        unmatched = interface.parameters.keys()

        for f in self.filter_list:
            name = f['name']
            filter_type = f['type']
            if name in interface.parameters:
                if name in unmatched:
                    unmatched.remove(name)
                if interface.parameters[
                        name].param_type == 'file' and filter_type not in FILE_TYPES:
                    raise InvalidDataFilter(
                        'MISMATCHED_TYPE',
                        'Interface parameter is a file type and requires a file type filter.'
                    )
                if interface.parameters[
                        name].param_type == 'json' and filter_type in FILE_TYPES:
                    raise InvalidDataFilter(
                        'MISMATCHED_TYPE',
                        'Interface parameter is a json type and will not work with a file type filter.'
                    )
                if interface.parameters[name].param_type == 'json':
                    if interface.parameters[
                            name].json_type in STRING_TYPES and filter_type not in STRING_TYPES:
                        raise InvalidDataFilter(
                            'MISMATCHED_TYPE',
                            'Interface parameter is a string and filter is not a string type filter'
                        )
                    if interface.parameters[
                            name].json_type in NUMBER_TYPES and filter_type not in NUMBER_TYPES:
                        raise InvalidDataFilter(
                            'MISMATCHED_TYPE',
                            'Interface parameter is a number and filter is not a number type filter'
                        )
                    if interface.parameters[
                            name].json_type in BOOL_TYPES and filter_type not in BOOL_TYPES:
                        raise InvalidDataFilter(
                            'MISMATCHED_TYPE',
                            'Interface parameter is a number and filter is not a number type filter'
                        )
                    json_type = interface.parameters[name].json_type
                    if json_type not in BOOL_TYPES and json_type not in STRING_TYPES and json_type not in NUMBER_TYPES:
                        raise InvalidDataFilter(
                            'MISMATCHED_TYPE',
                            'Interface parameter type is not supported by data filters'
                        )
            else:
                warnings.append(
                    ValidationWarning(
                        'UNMATCHED_FILTER',
                        'Filter with name \'%s\' does not have a matching parameter'
                    ))

        if unmatched:
            warnings.append(
                ValidationWarning(
                    'UNMATCHED_PARAMETERS',
                    'No matching filters for these parameters: \'%s\' ' %
                    unmatched))

        return warnings