Ejemplo n.º 1
0
def _validate_parameters(link, parameters):
    """
    Ensure that parameters passed to the link are correct.
    Raises a `ParameterError` if any parameters do not validate.
    """
    provided = set(parameters.keys())
    required = set([
        field.name for field in link.fields if field.required
    ])
    optional = set([
        field.name for field in link.fields if not field.required
    ])

    errors = {}

    # Determine if any required field names not supplied.
    missing = required - provided
    for item in missing:
        errors[item] = 'This parameter is required.'

    # Determine any parameter names supplied that are not valid.
    unexpected = provided - (optional | required)
    for item in unexpected:
        errors[item] = 'Unknown parameter.'

    if errors:
        raise exceptions.ParameterError(errors)
Ejemplo n.º 2
0
def _get_params(method, encoding, fields, params=None):
    """
    Separate the params into the various types.
    """
    if params is None:
        return empty_params

    field_map = {field.name: field for field in fields}

    path = {}
    query = {}
    data = {}
    files = {}

    errors = {}

    # Ensure graceful behavior in edge-case where both location='body' and
    # location='form' fields are present.
    seen_body = False

    for key, value in params.items():
        if key not in field_map or not field_map[key].location:
            # Default is 'query' for 'GET' and 'DELETE', and 'form' for others.
            location = 'query' if method in ('GET', 'DELETE') else 'form'
        else:
            location = field_map[key].location

        if location == 'form' and encoding == 'application/octet-stream':
            # Raw uploads should always use 'body', not 'form'.
            location = 'body'

        try:
            if location == 'path':
                path[key] = utils.validate_path_param(value)
            elif location == 'query':
                query[key] = utils.validate_query_param(value)
            elif location == 'body':
                data = utils.validate_body_param(value, encoding=encoding)
                seen_body = True
            elif location == 'form':
                if not seen_body:
                    data[key] = utils.validate_form_param(value,
                                                          encoding=encoding)
        except exceptions.ParameterError as exc:
            errors[key] = exc.message

    if errors:
        raise exceptions.ParameterError(errors)

    # Move any files from 'data' into 'files'.
    if isinstance(data, dict):
        for key, value in list(data.items()):
            if is_file(data[key]):
                files[key] = data.pop(key)

    return Params(path, query, data, files)
def _validate_form_object(value, allow_files=False):
    """
    Ensure that `value` can be encoded as form data or as query parameters.
    """
    if not isinstance(value, dict):
        msg = 'Must be an object.'
        raise exceptions.ParameterError(msg)
    return {
        text_type(item_key): _validate_form_field(item_val, allow_files=allow_files)
        for item_key, item_val in value.items()
    }
Ejemplo n.º 4
0
def validate_body_param(value, encoding):
    if encoding == 'application/json':
        return _validate_json_data(value)
    elif encoding == 'multipart/form-data':
        return _validate_form_object(value, allow_files=True)
    elif encoding == 'application/x-www-form-urlencoded':
        return _validate_form_object(value)
    elif encoding == 'application/octet-stream':
        if not is_file(value):
            msg = 'Must be an file upload.'
            raise exceptions.ParameterError(msg)
        return value
    msg = 'Unsupported encoding "%s" for outgoing request.'
    raise exceptions.NetworkError(msg % encoding)
Ejemplo n.º 5
0
def _validate_json_data(value):
    """
    Ensure that `value` can be encoded into JSON.
    """
    if (value is None) or isinstance(value, (bool, int, float, string_types)):
        return value
    elif isinstance(value, (list, tuple)) and not is_file(value):
        return [_validate_json_data(item) for item in value]
    elif isinstance(value, dict):
        return {
            text_type(item_key): _validate_json_data(item_val)
            for item_key, item_val in value.items()
        }

    msg = 'Must be a JSON primative.'
    raise exceptions.ParameterError(msg)
def _validate_form_field(value, allow_files=False, allow_list=True):
    """
    Ensure that `value` can be encoded as a single form data or a query parameter.
    Basic types that has a simple string representation are supported.
    A list of basic types is also valid.
    """
    if isinstance(value, string_types):
        return value
    elif isinstance(value, bool) or (value is None):
        return {True: 'true', False: 'false', None: ''}[value]
    elif isinstance(value, (int, float)):
        return "%s" % value
    elif allow_list and isinstance(value, (list, tuple)) and not is_file(value):
        # Only the top-level element may be a list.
        return [
            _validate_form_field(item, allow_files=False, allow_list=False)
            for item in value
        ]
    elif allow_files and is_file(value):
        return value

    msg = 'Must be a primative type.'
    raise exceptions.ParameterError(msg)
Ejemplo n.º 7
0
def validate_path_param(value):
    value = _validate_form_field(value, allow_list=False)
    if not value:
        msg = 'Parameter %s: May not be empty.'
        raise exceptions.ParameterError(msg)
    return value