def load(req): """Reads request body, raising an exception if it is not JSON. :param req: The request object to read from :type req: falcon.Request :return: a dictionary decoded from the JSON stream :rtype: dict :raises: wsgi_errors.HTTPBadRequestBody """ try: return json_utils.read_json(req.stream, req.content_length) except (json_utils.MalformedJSON, json_utils.OverflowedJSONInteger) as ex: LOG.exception(ex) raise wsgi_errors.HTTPBadRequestBody('JSON could not be parsed.')
def load(req): """Reads request body, raising an exception if it is not JSON. :param req: The request object to read from :type req: falcon.Request :return: a dictionary decoded from the JSON stream :rtype: dict :raises: wsgi_errors.HTTPBadRequestBody """ try: return json_utils.read_json(req.stream, req.content_length) except (json_utils.MalformedJSON, json_utils.OverflowedJSONInteger) as ex: LOG.exception(ex) raise wsgi_errors.HTTPBadRequestBody( 'JSON could not be parsed.' )
def filter_stream(stream, len, spec=None, doctype=JSONObject): """Reads, deserializes, and validates a document from a stream. :param stream: file-like object from which to read an object or array of objects. :param len: number of bytes to read from stream :param spec: (Default None) Iterable describing expected fields, yielding tuples with the form of: (field_name, value_type). Note that value_type may either be a Python type, or the special string '*' to accept any type. If spec is None, the incoming documents will not be validated. :param doctype: type of document to expect; must be either JSONObject or JSONArray. :raises: HTTPBadRequest, HTTPServiceUnavailable :returns: A sanitized, filtered version of the document list read from the stream. If the document contains a list of objects, each object will be filtered and returned in a new list. If, on the other hand, the document is expected to contain a single object, that object will be filtered and returned as a single-element iterable. """ if len is None: description = _(u'Request body can not be empty') raise errors.HTTPBadRequestBody(description) try: # TODO(kgriffs): read_json should stream the resulting list # of messages, returning a generator rather than buffering # everything in memory (bp/streaming-serialization). document = utils.read_json(stream, len) except utils.MalformedJSON as ex: LOG.debug(ex) description = _(u'Request body could not be parsed.') raise errors.HTTPBadRequestBody(description) except utils.OverflowedJSONInteger as ex: LOG.debug(ex) description = _(u'JSON contains integer that is too large.') raise errors.HTTPBadRequestBody(description) except Exception as ex: # Error while reading from the network/server LOG.exception(ex) description = _(u'Request body could not be read.') raise errors.HTTPServiceUnavailable(description) if doctype is JSONObject: if not isinstance(document, JSONObject): raise errors.HTTPDocumentTypeNotSupported() return (document, ) if spec is None else (filter(document, spec), ) if doctype is JSONArray: if not isinstance(document, JSONArray): raise errors.HTTPDocumentTypeNotSupported() if spec is None: return document return [filter(obj, spec) for obj in document] raise TypeError('doctype must be either a JSONObject or JSONArray')
def filter_stream(stream, len, spec=None, doctype=JSONObject): """Reads, deserializes, and validates a document from a stream. :param stream: file-like object from which to read an object or array of objects. :param len: number of bytes to read from stream :param spec: (Default None) Iterable describing expected fields, yielding tuples with the form of: (field_name, value_type). Note that value_type may either be a Python type, or the special string '*' to accept any type. If spec is None, the incoming documents will not be validated. :param doctype: type of document to expect; must be either JSONObject or JSONArray. :raises: HTTPBadRequest, HTTPServiceUnavailable :returns: A sanitized, filtered version of the document list read from the stream. If the document contains a list of objects, each object will be filtered and returned in a new list. If, on the other hand, the document is expected to contain a single object, that object will be filtered and returned as a single-element iterable. """ if len is None: description = _(u'Request body can not be empty') raise errors.HTTPBadRequestBody(description) try: # TODO(kgriffs): read_json should stream the resulting list # of messages, returning a generator rather than buffering # everything in memory (bp/streaming-serialization). document = utils.read_json(stream, len) except utils.MalformedJSON as ex: LOG.debug(ex) description = _(u'Request body could not be parsed.') raise errors.HTTPBadRequestBody(description) except utils.OverflowedJSONInteger as ex: LOG.debug(ex) description = _(u'JSON contains integer that is too large.') raise errors.HTTPBadRequestBody(description) except Exception as ex: # Error while reading from the network/server LOG.exception(ex) description = _(u'Request body could not be read.') raise errors.HTTPServiceUnavailable(description) if doctype is JSONObject: if not isinstance(document, JSONObject): raise errors.HTTPDocumentTypeNotSupported() return (document,) if spec is None else (filter(document, spec),) if doctype is JSONArray: if not isinstance(document, JSONArray): raise errors.HTTPDocumentTypeNotSupported() if spec is None: return document return [filter(obj, spec) for obj in document] raise TypeError('doctype must be either a JSONObject or JSONArray')