utils/param_parse.py
def param_parser(key, *other_keys,
                 default=Unset, empty=Unset, required=False, strip=False, multi=False):
    """
    Decorator that coverts a parsing function into a full param parser.

    The parsing functions take two strings - the param key and value - and return the parsed
    (and validated, if applicable) value. InvalidParamError should be raised if parsing(/validation)
    fails.

    The returned param parser function takes a dict of params, and attempts to find and parse a
    value for one of the keys listed. Each key is tried in turn, with the first key present in the
    params dict used (regardless of its value).

    If a key is found but the value is empty, `empty` is used. `empty` is `Unset` by default.

    If none of the keys are found or the value is found to be `Unset`, `default` is used.
    `default` is `Unset` by default.

    If the value is still found to be `Unset` and the param is `required`, RequiredParamError is
    raised. If none of the keys were found, the first key is used as the required param.

    If `strip` is set, whitespace is stripped from the start and end of values before parsing.

    If `multi` is set, an array of sub values is parsed. If `multi` is a string, the value is split
    by that string, e.g. ','. If it is any other truthy value, `.getall()` is used to get the value
    of all instances of the key in the params. Empty string sub values are removed, as are sub
    values that parse to `Unset`. `strip` applies to sub values. `default` and `empty` apply to the
    param as a whole, so should be arrays. `required` also applies to the param as a whole.
    """

    def decorator(parse_func):

        def parse_key(params, k):
            v = params[k]

            if multi:
                if isinstance(multi, str):
                    v = params[k].split(multi)
                else:
                    v = params.getall(k)

                if strip:
                    v = [sv.strip() for sv in v]

                v = [sv for sv in v if sv != '']

                v = [parse_func(k, sv) for sv in v]
                v = [sv for sv in v if sv is not Unset]

                if not v:
                    return empty

                return v

            else:
                v = params[k]

                if strip:
                    v = v.strip()

                if v == '':
                    return empty

                return parse_func(k, v)

        def parse_keys(params, keys):
            for k in keys:
                if k in params:
                    v = parse_key(params, k)

                    if v is Unset:
                        v = default

                    if required and v is Unset:
                        raise RequiredParamError(k)

                    return v

            return default

        def wrapper(params):
            v = parse_keys(params, [key, *other_keys])

            if required and v is Unset:
                raise RequiredParamError(key)

            return v

        return wrapper

    return decorator

    Decorator that coverts a parsing function into a full param parser.

    The parsing functions take two strings - the param key and value - and return the parsed
    (and validated, if applicable) value. InvalidParamError should be raised if parsing(/validation)
    fails.

    The returned param parser function takes a dict of params, and attempts to find and parse a
    value for one of the keys listed. Each key is tried in turn, with the first key present in the
    params dict used (regardless of its value).

    If a key is found but the value is empty, `empty` is used. `empty` is `Unset` by default.

    If none of the keys are found or the value is found to be `Unset`, `default` is used.
    `default` is `Unset` by default.

    If the value is still found to be `Unset` and the param is `required`, RequiredParamError is
    raised. If none of the keys were found, the first key is used as the required param.

    If `strip` is set, whitespace is stripped from the start and end of values before parsing.

    If `multi` is set, an array of sub values is parsed. If `multi` is a string, the value is split
    by that string, e.g. ','. If it is any other truthy value, `.getall()` is used to get the value
    of all instances of the key in the params. Empty string sub values are removed, as are sub
    values that parse to `Unset`. `strip` applies to sub values. `default` and `empty` apply to the
    param as a whole, so should be arrays. `required` also applies to the param as a whole.
    
Decorator that coverts a parsing function into a full param parser.
The parsing functions take two strings - the param key and value - and return the parsed
(and validated, if applicable) value. InvalidParamError should be raised if parsing(/validation)
fails.

The returned param parser function takes a dict of params, and attempts to find and parse a
value for one of the keys listed. Each key is tried in turn, with the first key present in the
params dict used (regardless of its value).

If a key is found but the value is empty, `empty` is used. `empty` is `Unset` by default.

If none of the keys are found or the value is found to be `Unset`, `default` is used.
`default` is `Unset` by default.

If the value is still found to be `Unset` and the param is `required`, RequiredParamError is
raised. If none of the keys were found, the first key is used as the required param.

If `strip` is set, whitespace is stripped from the start and end of values before parsing.

If `multi` is set, an array of sub values is parsed. If `multi` is a string, the value is split
by that string, e.g.
Decorator that coverts a parsing function into a full param parser . The parsing functions take two strings - the param key and value - and return the parsed ( and validated if applicable ) value . InvalidParamError should be raised if parsing ( / validation ) fails . The returned param parser function takes a dict of params and attempts to find and parse a value for one of the keys listed . Each key is tried in turn with the first key present in the params dict used ( regardless of its value ) . If a key is found but the value is empty ` empty ` is used . ` empty ` is ` Unset ` by default . If none of the keys are found or the value is found to be ` Unset ` ` default ` is used . ` default ` is ` Unset ` by default . If the value is still found to be ` Unset ` and the param is ` required ` RequiredParamError is raised . If none of the keys were found the first key is used as the required param . If ` strip ` is set whitespace is stripped from the start and end of values before parsing . If ` multi ` is set an array of sub values is parsed . If ` multi ` is a string the value is split by that string e . g .
def param_parser(key, *other_keys,
                 default=Unset, empty=Unset, required=False, strip=False, multi=False):
    def decorator(parse_func):
        def parse_key(params, k):
            v = params[k]
            if multi:
                if isinstance(multi, str):
                    v = params[k].split(multi)
                else:
                    v = params.getall(k)
                if strip:
                    v = [sv.strip() for sv in v]
                v = [sv for sv in v if sv != '']
                v = [parse_func(k, sv) for sv in v]
                v = [sv for sv in v if sv is not Unset]
                if not v:
                    return empty
                return v
            else:
                v = params[k]
                if strip:
                    v = v.strip()
                if v == '':
                    return empty
                return parse_func(k, v)
        def parse_keys(params, keys):
            for k in keys:
                if k in params:
                    v = parse_key(params, k)
                    if v is Unset:
                        v = default
                    if required and v is Unset:
                        raise RequiredParamError(k)
                    return v
            return default
        def wrapper(params):
            v = parse_keys(params, [key, *other_keys])
            if required and v is Unset:
                raise RequiredParamError(key)
            return v
        return wrapper
    return decorator
def param_parser ( key , * other_keys , default = Unset , empty = Unset , required = False , strip = False , multi = False ) : def decorator ( parse_func ) : def parse_key ( params , k ) : v = params [ k ] if multi : if isinstance ( multi , str ) : v = params [ k ] . split ( multi ) else : v = params . getall ( k ) if strip : v = [ sv . strip ( ) for sv in v ] v = [ sv for sv in v if sv != '' ] v = [ parse_func ( k , sv ) for sv in v ] v = [ sv for sv in v if sv is not Unset ] if not v : return empty return v else : v = params [ k ] if strip : v = v . strip ( ) if v == '' : return empty return parse_func ( k , v ) def parse_keys ( params , keys ) : for k in keys : if k in params : v = parse_key ( params , k ) if v is Unset : v = default if required and v is Unset : raise RequiredParamError ( k ) return v return default def wrapper ( params ) : v = parse_keys ( params , [ key , * other_keys ] ) if required and v is Unset : raise RequiredParamError ( key ) return v return wrapper return decorator
Decorator that coverts a parsing function into a full param parser.
Decorator that coverts a parsing function into a full param parser .
"""
    Decorator that coverts a parsing function into a full param parser.

    The parsing functions take two strings - the param key and value - and return the parsed
    (and validated, if applicable) value. InvalidParamError should be raised if parsing(/validation)
    fails.

    The returned param parser function takes a dict of params, and attempts to find and parse a
    value for one of the keys listed. Each key is tried in turn, with the first key present in the
    params dict used (regardless of its value).

    If a key is found but the value is empty, `empty` is used. `empty` is `Unset` by default.

    If none of the keys are found or the value is found to be `Unset`, `default` is used.
    `default` is `Unset` by default.

    If the value is still found to be `Unset` and the param is `required`, RequiredParamError is
    raised. If none of the keys were found, the first key is used as the required param.

    If `strip` is set, whitespace is stripped from the start and end of values before parsing.

    If `multi` is set, an array of sub values is parsed. If `multi` is a string, the value is split
    by that string, e.g. ','. If it is any other truthy value, `.getall()` is used to get the value
    of all instances of the key in the params. Empty string sub values are removed, as are sub
    values that parse to `Unset`. `strip` applies to sub values. `default` and `empty` apply to the
    param as a whole, so should be arrays. `required` also applies to the param as a whole.
    """
key
default
empty
required
strip
multi