def require_params(self, req): """ Require all parameters from request that are defined for this resource. Raises ``falcon.errors.HTTPMissingParam`` exception if any of required parameters is missing and ``falcon.errors.HTTPInvalidParam`` if any of parameters could not be understood (wrong format). Args: req (falcon.Request): request object """ # TODO: handle specifying parameter multiple times in query string! params = {} for name, param in self.params.items(): if name not in req.params and param.required: # we could simply raise with this single param or use get_param # with required=True parameter but for client convenience # we prefer to list all missing params that are required missing = set( p for p in self.params if self.params[p].required) - set( req.params.keys()) raise errors.HTTPMissingParam(", ".join(missing)) elif name in req.params or param.default: # Note: lack of key in req.params means it was not specified # so unless there is default value it will not be included in # output params dict. # This way we have explicit information that param was # not specified. Using None would not be as good because param # class can also return None from `.value()` method as a valid # translated value. try: if param.many: # params with "many" enabled need special care params[name] = req.get_param_as_list( name, param.value, ) or [param.default and param.value(param.default)] else: # note that if many==False and query parameter # occurs multiple times in qs then it is # **unspecified** which one will be used. See: # http://falcon.readthedocs.org/en/latest/api/request_and_response.html#falcon.Request.get_param # noqa params[name] = param.value( req.get_param(name, default=param.default)) except ValueError as err: raise errors.HTTPInvalidParam(str(err), name) return params
def get_param_as_date(self, name, format_string='%Y-%m-%d', required=False, store=None): """Return the value of a query string parameter as a date. Args: name (str): Parameter name, case-sensitive (e.g., 'ids'). format_string (str): String used to parse the param value into a date. Any format recognized by strptime() is supported. (default ``"%Y-%m-%d"``) required (bool, optional): Set to ``True`` to raise ``HTTPBadRequest`` instead of returning ``None`` when the parameter is not found (default ``False``). store (dict, optional): A ``dict``-like object in which to place the value of the param, but only if the param is found (default ``None``). Returns: datetime.date: The value of the param if it is found and can be converted to a ``date`` according to the supplied format string. If the param is not found, returns ``None`` unless required is ``True``. Raises: HTTPBadRequest: A required param is missing from the request. HTTPInvalidParam: A transform function raised an instance of ``ValueError``. """ param_value = self.get_param(name, required=required) if param_value is None: return None try: date = strptime(param_value, format_string).date() except ValueError: msg = 'The date value does not match the required format.' raise errors.HTTPInvalidParam(msg, name) if store is not None: store[name] = date return date
def get_param_as_dict(self, name, required=False, store=None): """Return the value of a query string parameter as a dict. Given a JSON value, parse and return it as a dict. Args: name (str): Parameter name, case-sensitive (e.g., 'payload'). required (bool, optional): Set to ``True`` to raise ``HTTPBadRequest`` instead of returning ``None`` when the parameter is not found (default ``False``). store (dict, optional): A ``dict``-like object in which to place the value of the param, but only if the param is found (default ``None``). Returns: dict: The value of the param if it is found. Otherwise, returns ``None`` unless required is ``True``. Raises: HTTPBadRequest: A required param is missing from the request. HTTPInvalidParam: The parameter's value could not be parsed as JSON. """ param_value = self.get_param(name, required=required) if param_value is None: return None try: val = json.loads(param_value) except ValueError: msg = 'It could not be parsed as JSON.' raise errors.HTTPInvalidParam(msg, name) if store is not None: store[name] = val return val
def get_param_as_bool(self, name, required=False, store=None, blank_as_true=False): """Return the value of a query string parameter as a boolean The following boolean strings are supported:: TRUE_STRINGS = ('true', 'True', 'yes', '1') FALSE_STRINGS = ('false', 'False', 'no', '0') Args: name (str): Parameter name, case-sensitive (e.g., 'detailed'). required (bool, optional): Set to ``True`` to raise ``HTTPBadRequest`` instead of returning ``None`` when the parameter is not found or is not a recognized boolean string (default ``False``). store (dict, optional): A ``dict``-like object in which to place the value of the param, but only if the param is found (default ``None``). blank_as_true (bool): If ``True``, an empty string value will be treated as ``True``. Normally empty strings are ignored; if you would like to recognize such parameters, you must set the `keep_blank_qs_values` request option to ``True``. Request options are set globally for each instance of ``falcon.API`` through the `req_options` attribute. Returns: bool: The value of the param if it is found and can be converted to a ``bool``. If the param is not found, returns ``None`` unless required is ``True``. Raises: HTTPBadRequest: A required param is missing from the request. """ params = self._params # PERF: Use if..in since it is a good all-around performer; we don't # know how likely params are to be specified by clients. if name in params: val = params[name] if isinstance(val, list): val = val[-1] if val in TRUE_STRINGS: val = True elif val in FALSE_STRINGS: val = False elif blank_as_true and not val: val = True else: msg = 'The value of the parameter must be "true" or "false".' raise errors.HTTPInvalidParam(msg, name) if store is not None: store[name] = val return val if not required: return None raise errors.HTTPMissingParam(name)
def get_param_as_int(self, name, required=False, min=None, max=None, store=None): """Return the value of a query string parameter as an int. Args: name (str): Parameter name, case-sensitive (e.g., 'limit'). required (bool, optional): Set to ``True`` to raise ``HTTPBadRequest`` instead of returning ``None`` when the parameter is not found or is not an integer (default ``False``). min (int, optional): Set to the minimum value allowed for this param. If the param is found and it is less than min, an ``HTTPError`` is raised. max (int, optional): Set to the maximum value allowed for this param. If the param is found and its value is greater than max, an ``HTTPError`` is raised. store (dict, optional): A ``dict``-like object in which to place the value of the param, but only if the param is found (default ``None``). Returns: int: The value of the param if it is found and can be converted to an integer. If the param is not found, returns ``None``, unless `required` is ``True``. Raises HTTPBadRequest: The param was not found in the request, even though it was required to be there. Also raised if the param's value falls outside the given interval, i.e., the value must be in the interval: min <= value <= max to avoid triggering an error. """ params = self._params # PERF: Use if..in since it is a good all-around performer; we don't # know how likely params are to be specified by clients. if name in params: val = params[name] if isinstance(val, list): val = val[-1] try: val = int(val) except ValueError: msg = 'The value must be an integer.' raise errors.HTTPInvalidParam(msg, name) if min is not None and val < min: msg = 'The value must be at least ' + str(min) raise errors.HTTPInvalidParam(msg, name) if max is not None and max < val: msg = 'The value may not exceed ' + str(max) raise errors.HTTPInvalidParam(msg, name) if store is not None: store[name] = val return val if not required: return None raise errors.HTTPMissingParam(name)
def get_param_as_list(self, name, transform=None, required=False, store=None): """Return the value of a query string parameter as a list. List items must be comma-separated or must be provided as multiple instances of the same param in the query string ala *application/x-www-form-urlencoded*. Args: name (str): Parameter name, case-sensitive (e.g., 'ids'). transform (callable, optional): An optional transform function that takes as input each element in the list as a ``str`` and outputs a transformed element for inclusion in the list that will be returned. For example, passing ``int`` will transform list items into numbers. required (bool, optional): Set to ``True`` to raise ``HTTPBadRequest`` instead of returning ``None`` when the parameter is not found (default ``False``). store (dict, optional): A ``dict``-like object in which to place the value of the param, but only if the param is found (default ``None``). Returns: list: The value of the param if it is found. Otherwise, returns ``None`` unless required is True. Empty list elements will be discarded. For example, the following query strings would both result in `['1', '3']`:: things=1,,3 things=1&things=&things=3 Raises: HTTPBadRequest: A required param is missing from the request. HTTPInvalidParam: A transform function raised an instance of ``ValueError``. """ params = self._params # PERF: Use if..in since it is a good all-around performer; we don't # know how likely params are to be specified by clients. if name in params: items = params[name] # NOTE(warsaw): When a key appears multiple times in the request # query, it will already be represented internally as a list. # NOTE(kgriffs): Likewise for comma-delimited values. if not isinstance(items, list): items = [items] # PERF(kgriffs): Use if-else rather than a DRY approach # that sets transform to a passthrough function; avoids # function calling overhead. if transform is not None: try: items = [transform(i) for i in items] except ValueError: msg = 'The value is not formatted correctly.' raise errors.HTTPInvalidParam(msg, name) if store is not None: store[name] = items return items if not required: return None raise errors.HTTPMissingParam(name)