示例#1
0
def _verify_parameters(
    path: str,
    parameters: Sequence[OpenAPIParameter],
):
    """Verifies matching of parameters to the placeholders used in an URL-Template

    This works both ways, ensuring that no parameter is supplied which is then not used and that
    each template-variable in the URL-template has a corresponding parameter supplied,
    either globally or locally.

    Args:
        path:
            The URL-Template, for eample: '/user/{username}'

        parameters:
            A list of parameters. A parameter can either be a string referencing a
            globally defined parameter by name, or a dict containing a full parameter.

    Examples:

        In case of success, this function will return nothing.

          >>> _verify_parameters('/foo/{bar}', [{'name': 'bar', 'in': 'path'}])

        Yet, when problems are found, ValueErrors are raised.

          >>> _verify_parameters('/foo', [{'name': 'foo', 'in': 'path'}])
          Traceback (most recent call last):
          ...
          ValueError: Param 'foo', which is specified as 'path', not used in path. Found params: []

          >>> _verify_parameters('/foo/{bar}', [])
          Traceback (most recent call last):
          ...
          ValueError: Param 'bar', which is used in the HTTP path, was not specified in []

    Returns:
        Nothing.

    Raises:
        ValueError in case of a mismatch.

    """
    param_names = _names_of(parameters)
    path_params = path_parameters(path)
    for path_param in path_params:
        if path_param not in param_names:
            raise ValueError(
                f"Param {path_param!r}, which is used in the HTTP path, was not specified in "
                f"{parameters!r}")

    for param in parameters:
        if isinstance(
                param, dict
        ) and param['in'] == 'path' and param['name'] not in path_params:
            raise ValueError(
                f"Param {repr(param['name'])}, which is specified as 'path', not used in path. "
                f"Found params: {path_params}")

    find_all_parameters(parameters, errors='raise')
示例#2
0
 def _param_key(_path, _parameters):
     # We key on _all_ required parameters, regardless their type.
     _param_names = set()
     for _param in _parameters:
         if isinstance(_param, dict) and _param.get('required', True):
             _param_names.add(_param['name'])
     for _param_name in path_parameters(_path):
         _param_names.add(_param_name)
     return tuple(sorted(_param_names))
示例#3
0
 def _param_key(_path, _parameters):
     # We key on _all_ required parameters, regardless their type.
     _param_names = set()
     for _param in _parameters:
         if ("schema" not in _param and isinstance(_param, dict)
                 and _param.get("required", True)):
             _param_names.add(_param["name"])
     for _param_name in path_parameters(_path):
         _param_names.add(_param_name)
     return tuple(sorted(_param_names))
示例#4
0
def _verify_parameters(
    path: str,
    path_schema: Optional[Type[Schema]],
):
    """Verifies matching of parameters to the placeholders used in an URL-Template

    This works both ways, ensuring that no parameter is supplied which is then not used and that
    each template-variable in the URL-template has a corresponding parameter supplied,
    either globally or locally.

    Args:
        path:
            The URL-Template, for eample: '/user/{username}'

        path_schema:
            A marshmallow schema which is used for path parameter validation.

    Examples:

        In case of success, this function will return nothing.

          >>> from cmk.fields import String
          >>> class Params(Schema):
          ...      bar = String()

          >>> _verify_parameters('/foo/{bar}', Params)
          >>> _verify_parameters('/foo', None)

        Yet, when problems are found, ValueErrors are raised.

          >>> _verify_parameters('/foo', Params)
          Traceback (most recent call last):
          ...
          ValueError: Params {'bar'} not used in path /foo. Found params: set()

          >>> _verify_parameters('/foo/{bar}', None)
          Traceback (most recent call last):
          ...
          ValueError: Params {'bar'} of path /foo/{bar} were not given in schema parameters set()

    Returns:
        Nothing.

    Raises:
        ValueError in case of a mismatch.

    """
    if path_schema is None:
        schema_params = set()
    else:
        schema = path_schema()
        schema_params = set(schema.declared_fields.keys())

    path_params = set(path_parameters(path))
    missing_in_schema = path_params - schema_params
    missing_in_path = schema_params - path_params

    if missing_in_schema:
        raise ValueError(
            f"Params {missing_in_schema!r} of path {path} were not given in schema parameters "
            f"{schema_params!r}")

    if missing_in_path:
        raise ValueError(
            f"Params {missing_in_path!r} not used in path {path}. "
            f"Found params: {path_params!r}")
示例#5
0
def _make_url(
    path: str,
    param_spec: Sequence[PrimitiveParameter],
    param_val: Dict[str, str],
) -> str:
    """Make a concrete URL according to parameter specs and value-mappings.

    Examples:

        For use in path

        >>> _make_url('/foo/{host}', [{'name': 'host', 'in': 'path'}], {'host': 'example.com'})
        '/foo/example.com'

        Or in query-string:

        >>> _make_url('/foo', [{'name': 'host', 'in': 'query'}], {'host': 'example.com'})
        '/foo?host=example.com'

        >>> _make_url('/foo', [{'name': 'host', 'in': 'query', 'required': False}],
        ...           {'host': 'example.com'})
        '/foo?host=example.com'

        >>> _make_url('/foo', [{'name': 'host', 'in': 'query', 'required': False}], {})
        '/foo'

        Some edge-cases which are caught.

        >>> _make_url('/foo', [{'name': 'host', 'in': 'path'}], {})
        Traceback (most recent call last):
        ...
        ValueError: No parameter mapping for required parameter 'host'.

        >>> _make_url('/foo', [{'name': 'host', 'in': 'path'}], {'host': 'example.com'})
        Traceback (most recent call last):
        ...
        ValueError: Parameter 'host' (required path-parameter), not found in path '/foo'

        >>> import pytest
        >>> # This exceptions gets thrown by another function, so we don't care about the wording.
        >>> with pytest.raises(ValueError):
        ...     _make_url('/foo/{host}', [], {'host': 'example.com'})

    Args:
        path:
            The path. May have "{variable_name}" template parts in the path-name or not.

        param_spec:
            A list of parameters.

        param_val:
            A mapping of parameter-names to their desired values. Used to fill out the templates.

    Returns:
        The formatted path, query-string appended if applicable.

    """
    path_params: Dict[str, PrimitiveParameter] = {}
    qs = []
    for p in param_spec:
        param_name = p['name']
        if param_name not in param_val:
            if p.get('required', True):
                raise ValueError(f"No parameter mapping for required parameter {param_name!r}.")
            # We skip optional parameters, when we don't have values for them.
            continue

        param_value = param_val[param_name]
        if p['in'] == 'query':
            qs.append(f"{param_name}={param_value}")
        elif p['in'] == 'path':
            if param_name not in path_parameters(path):
                raise ValueError(f"Parameter {param_name!r} (required path-parameter), "
                                 f"not found in path {path!r}")
            path_params[param_name] = {'example': param_value}

    query_string = '&'.join(qs)
    rv = fill_out_path_template(path, path_params)
    if query_string:
        rv += f"?{query_string}"
    return rv