Exemple #1
0
def interval_validator(compiler, min='0s', max='365d'):
    """Time interval validator, convert value to seconds

    Supported time units:
        s: seconds, eg: 10s
        m: minutes, eg: 10m
        h: hours, eg: 1h
        d: days, eg: 7d
    """
    try:
        min = parse_interval(min)
    except (IndexError, KeyError, ValueError):
        raise SchemaError('invalid min value') from None
    try:
        max = parse_interval(max)
    except (IndexError, KeyError, ValueError):
        raise SchemaError('invalid max value') from None

    def validate(value):
        try:
            value = parse_interval(value)
        except (IndexError, KeyError, ValueError):
            raise Invalid("invalid interval") from None
        if value < min:
            raise Invalid("interval must >= {}".format(min))
        if value > max:
            raise Invalid("interval must <= {}".format(max))
        return value

    return validate
Exemple #2
0
def _parse_fields(fields, extra_fields):
    """
    >>> fields, extra_fields = _parse_fields('a,b', ''' c d
    ...     e''')
    >>> fields == {'a', 'b'}
    True
    >>> extra_fields == {'c', 'd', 'e'}
    True
    >>> _parse_fields('a,b', 'b,c,d')
    Traceback (most recent call last):
    ...
    validr._exception_c.SchemaError: duplicated fields b
    """
    def _parse_one(text, error_message):
        if not text:
            return set()
        try:
            text = text.strip()
        except (TypeError, AttributeError):
            raise SchemaError(error_message) from None
        return set(text.replace(',', ' ').split())

    fields = _parse_one(fields, 'invalid fields')
    extra_fields = _parse_one(extra_fields, 'invalid extra_fields')
    if (not fields) and (not extra_fields):
        raise SchemaError("no fields provided")
    duplicated_fields = ','.join(fields & extra_fields)
    if duplicated_fields:
        raise SchemaError(f"duplicated fields {duplicated_fields}")
    return fields, extra_fields
Exemple #3
0
def url_validator(compiler, scheme='http https', default_schema=None, maxlen=1024, relaxed=False):
    """
    Args:
        default_schema: 接受没有scheme的url并尝试修正
        relaxed: accept not strict url
    """
    if relaxed:
        return Compiler().compile(T.url.maxlen(maxlen).scheme(scheme))
    schemes = set(scheme.replace(',', ' ').split(' '))
    if default_schema and default_schema not in schemes:
        raise SchemaError('invalid default_schema {}'.format(default_schema))
    _django_validate_url = URLValidator(schemes=schemes)

    def validate(value):
        if default_schema:
            value = coerce_url(value, default_schema=default_schema)
        try:
            _django_validate_url(value)
        except ValidationError:
            # TODO: access ValidationError.messages will cause error when
            # django/i18n not setup, maybe use validators package instead
            # raise Invalid(','.join(ex.messages).rstrip('.'))
            raise Invalid('invalid or incorrect url format')
        if len(value) > maxlen:
            raise Invalid(f'url length must <= {maxlen}')
        return value

    return validate
Exemple #4
0
def cursor_validator(compiler, keys=None, output_object=False, base64=False):
    """Cursor: k1:v1,k2:v2"""
    if keys:
        try:
            keys = set(keys.strip().replace(',', ' ').split())
        except (TypeError, ValueError):
            raise SchemaError('invalid cursor keys')

    def validate(value):
        try:
            if not isinstance(value, Cursor):
                if base64:
                    value = urlsafe_b64decode(value.encode('ascii')).decode('utf-8')
                value = Cursor.from_string(value, keys)
            else:
                value._check_missing_keys(keys)
        except (UnicodeEncodeError, UnicodeDecodeError, ValueError) as ex:
            raise Invalid(str(ex)) from None
        if output_object:
            return value
        value = str(value)
        if base64:
            value = urlsafe_b64encode(value.encode('utf-8')).decode()
        return value

    return validate
Exemple #5
0
def _parse_doc(doc, mark):
    """
    Parse YAML syntax data from doc

    if doc is None, return ('', OrderedDict())
    if doc has no YAML data, return (doc, OrderedDict())
    else, parse YAML data, return (doc, data)

    Args:
        doc (str): doc to be parsed
        mark (Regex): which marks the start position of data
    Returns:
        tuple(desc, data): data is an OrderedDict contains information of doc
    """
    if doc is None:
        return '', OrderedDict()
    match = mark.search(doc)
    if not match:
        return textwrap.dedent(doc).strip(), OrderedDict()
    start = match.start()
    yamltext = textwrap.dedent(doc[start:])
    try:
        data = yaml.load(yamltext)
    except yaml.parser.ParserError as ex:
        raise SchemaError(str(ex)) from None
    return textwrap.dedent(doc[:start]).strip(), data
Exemple #6
0
 def _parse_one(text, error_message):
     if not text:
         return set()
     try:
         text = text.strip()
     except (TypeError, AttributeError):
         raise SchemaError(error_message) from None
     return set(text.replace(',', ' ').split())