def __call__(self, env, start_response): """WSGI "app" method Makes instances of API callable by any WSGI server. See also PEP 333. Args: env: A WSGI environment dictionary start_response: A WSGI helper method for setting status and headers on a response. """ req = Request(env) resp = Response() responder, params, na_responder = self._get_responder( req.path, req.method) try: responder(req, resp, **params) except HTTPError as ex: resp.status = ex.status if ex.headers is not None: resp.set_headers(ex.headers) if req.client_accepts('application/json'): resp.body = ex.json() # # Set status and headers # use_body = not helpers.should_ignore_body(resp.status, req.method) if use_body: helpers.set_content_length(resp) body = helpers.get_body(resp) else: # Default: return an empty body body = [] # Set content type if needed use_content_type = (body or req.method == 'HEAD' or resp.status == HTTP_416) if use_content_type: media_type = self._media_type else: media_type = None headers = resp._wsgi_headers(media_type) # Return the response per the WSGI spec start_response(resp.status, headers) return body
def __call__(self, env, start_response): """WSGI "app" method Makes instances of API callable by any WSGI server. See also PEP 333. Args: env: A WSGI environment dictionary start_response: A WSGI helper method for setting status and headers on a response. """ req = Request(env) resp = Response() responder, params, na_responder = self._get_responder( req.path, req.method) try: responder(req, resp, **params) except HTTPError as ex: resp.status = ex.status if ex.headers is not None: resp.set_headers(ex.headers) if req.client_accepts('application/json'): resp.body = ex.json() except TypeError as ex: # NOTE(kgriffs): Get the stack trace up here since we can just # use this convenience function which graps the last raised # exception context. stack_trace = traceback.format_exc() # See if the method doesn't support the given route's params, to # support assigning multiple routes to the same resource. try: argspec = responder.wrapped_argspec except AttributeError: argspec = inspect.getargspec(responder) # First three args should be (self, req, resp) if argspec.args[0] == 'self': offset = 3 else: offset = 2 args_needed = set(argspec.args[offset:]) args_given = set(params.keys()) # Reset the response resp = Response() # Does the responder require more or fewer args than given? if args_needed != args_given: req.log_error('A responder method could not be found with the ' 'correct arguments.') na_responder(req, resp) else: # Error caused by something else req.log_error('A responder method (on_*) raised TypeError. %s' % stack_trace) falcon.responders.internal_server_error(req, resp) # # Set status and headers # use_body = not helpers.should_ignore_body(resp.status, req.method) if use_body: helpers.set_content_length(resp) body = helpers.get_body(resp) else: # Default: return an empty body body = [] # Set content type if needed use_content_type = (body or req.method == 'HEAD' or resp.status == HTTP_416) if use_content_type: media_type = self._media_type else: media_type = None headers = resp._wsgi_headers(media_type) # Return the response per the WSGI spec start_response(resp.status, headers) return body
def __call__(self, env, start_response): """WSGI "app" method Makes instances of API callable by any WSGI server. See also PEP 333. Args: env: A WSGI environment dictionary start_response: A WSGI helper method for setting status and headers on a response. """ req = Request(env) resp = Response() responder, params = self._get_responder( req.path, req.method) try: # NOTE(kgriffs): Using an inner try..except in order to # address the case when err_handler raises HTTPError. # # NOTE(kgriffs): Coverage is giving false negatives, # so disabled on relevant lines. All paths are tested # afaict. try: responder(req, resp, **params) # pragma: no cover except Exception as ex: for err_type, err_handler in self._error_handlers: if isinstance(ex, err_type): err_handler(ex, req, resp, params) break # pragma: no cover else: # PERF(kgriffs): This will propagate HTTPError to # the handler below. It makes handling HTTPError # less efficient, but that is OK since error cases # don't need to be as fast as the happy path, and # indeed, should perhaps be slower to create # backpressure on clients that are issuing bad # requests. raise except HTTPError as ex: resp.status = ex.status if ex.headers is not None: resp.set_headers(ex.headers) if req.client_accepts('application/json'): resp.body = ex.json() # # Set status and headers # use_body = not helpers.should_ignore_body(resp.status, req.method) if use_body: helpers.set_content_length(resp) body = helpers.get_body(resp) else: # Default: return an empty body body = [] # Set content type if needed use_content_type = (body or req.method == 'HEAD' or resp.status == HTTP_416) if use_content_type: media_type = self._media_type else: media_type = None headers = resp._wsgi_headers(media_type) # Return the response per the WSGI spec start_response(resp.status, headers) return body
def __call__(self, env, start_response): """WSGI "app" method Makes instances of API callable by any WSGI server. See also PEP 333. Args: env: A WSGI environment dictionary start_response: A WSGI helper method for setting status and headers on a response. """ req = Request(env) resp = Response() responder, params, na_responder = self._get_responder( req.path, req.method) try: responder(req, resp, **params) except HTTPError as ex: resp.status = ex.status if ex.headers is not None: resp.set_headers(ex.headers) if req.client_accepts('application/json'): resp.body = ex.json() except TypeError as ex: # NOTE(kgriffs): Get the stack trace up here since we can just # use this convenience function which graps the last raised # exception context. stack_trace = traceback.format_exc() # See if the method doesn't support the given route's params, to # support assigning multiple routes to the same resource. try: argspec = responder.wrapped_argspec except AttributeError: argspec = inspect.getargspec(responder) # First three args should be (self, req, resp) if argspec.args[0] == 'self': offset = 3 else: offset = 2 args_needed = set(argspec.args[offset:]) args_given = set(params.keys()) # Reset the response resp = Response() # Does the responder require more or fewer args than given? if args_needed != args_given: req.log_error('A responder method could not be found with the ' 'correct arguments.') na_responder(req, resp) else: # Error caused by something else req.log_error( 'A responder method (on_*) raised TypeError. %s' % stack_trace) falcon.responders.internal_server_error(req, resp) # # Set status and headers # use_body = not helpers.should_ignore_body(resp.status, req.method) if use_body: helpers.set_content_length(resp) body = helpers.get_body(resp) else: # Default: return an empty body body = [] # Set content type if needed use_content_type = (body or req.method == 'HEAD' or resp.status == HTTP_416) if use_content_type: media_type = self._media_type else: media_type = None headers = resp._wsgi_headers(media_type) # Return the response per the WSGI spec start_response(resp.status, headers) return body
def __call__(self, env, start_response): """WSGI `app` method. Makes instances of API callable from a WSGI server. May be used to host an API or called directly in order to simulate requests when testing the API. See also PEP 3333. Args: env (dict): A WSGI environment dictionary start_response (callable): A WSGI helper function for setting status and headers on a response. """ req = self._request_type(env) resp = self._response_type() responder, params, resource = self._get_responder(req.path, req.method) try: # NOTE(kgriffs): Using an inner try..except in order to # address the case when err_handler raises HTTPError. # # NOTE(kgriffs): Coverage is giving false negatives, # so disabled on relevant lines. All paths are tested # afaict. try: responder(req, resp, **params) # pragma: no cover except Exception as ex: for err_type, err_handler in self._error_handlers: if isinstance(ex, err_type): err_handler(ex, req, resp, params) self._call_after_hooks(req, resp, resource) break # pragma: no cover else: # PERF(kgriffs): This will propagate HTTPError to # the handler below. It makes handling HTTPError # less efficient, but that is OK since error cases # don't need to be as fast as the happy path, and # indeed, should perhaps be slower to create # backpressure on clients that are issuing bad # requests. raise except HTTPError as ex: helpers.compose_error_response(req, resp, ex) self._call_after_hooks(req, resp, resource) # # Set status and headers # use_body = not helpers.should_ignore_body(resp.status, req.method) if use_body: helpers.set_content_length(resp) body = helpers.get_body(resp, env.get('wsgi.file_wrapper')) else: # Default: return an empty body body = [] # Set content type if needed use_content_type = (body or req.method == 'HEAD' or resp.status == HTTP_416) if use_content_type: media_type = self._media_type else: media_type = None headers = resp._wsgi_headers(media_type) # Return the response per the WSGI spec start_response(resp.status, headers) return body
def __call__(self, env, start_response): """WSGI `app` method. Makes instances of API callable from a WSGI server. May be used to host an API or called directly in order to simulate requests when testing the API. See also PEP 3333. Args: env (dict): A WSGI environment dictionary start_response (callable): A WSGI helper function for setting status and headers on a response. """ req = self._request_type(env) resp = self._response_type() resource = None try: # NOTE(warsaw): Moved this to inside the try except because it's # possible when using object-based traversal for _get_responder() # to fail. An example is a case where an object does not have the # requested next-hop child resource. In that case, the object # being asked to dispatch to its child will raise an HTTP # exception signalling the problem, e.g. a 404. responder, params, resource = self._get_responder(req) # NOTE(kgriffs): Using an inner try..except in order to # address the case when err_handler raises HTTPError. # # NOTE(kgriffs): Coverage is giving false negatives, # so disabled on relevant lines. All paths are tested # afaict. try: responder(req, resp, **params) # pragma: no cover except Exception as ex: for err_type, err_handler in self._error_handlers: if isinstance(ex, err_type): err_handler(ex, req, resp, params) self._call_after_hooks(req, resp, resource) break # pragma: no cover else: # PERF(kgriffs): This will propagate HTTPError to # the handler below. It makes handling HTTPError # less efficient, but that is OK since error cases # don't need to be as fast as the happy path, and # indeed, should perhaps be slower to create # backpressure on clients that are issuing bad # requests. raise except HTTPError as ex: helpers.compose_error_response(req, resp, ex) self._call_after_hooks(req, resp, resource) # # Set status and headers # use_body = not helpers.should_ignore_body(resp.status, req.method) if use_body: helpers.set_content_length(resp) body = helpers.get_body(resp, env.get("wsgi.file_wrapper")) else: # Default: return an empty body body = [] # Set content type if needed use_content_type = body or req.method == "HEAD" or resp.status == HTTP_416 if use_content_type: media_type = self._media_type else: media_type = None headers = resp._wsgi_headers(media_type) # Return the response per the WSGI spec start_response(resp.status, headers) return body
def __call__(self, env, start_response): """WSGI `app` method. Makes instances of API callable from a WSGI server. May be used to host an API or called directly in order to simulate requests when testing the API. See also PEP 3333. Args: env (dict): A WSGI environment dictionary start_response (callable): A WSGI helper function for setting status and headers on a response. """ req = self._request_type(env) resp = self._response_type() responder, params = self._get_responder( req.path, req.method) try: # NOTE(kgriffs): Using an inner try..except in order to # address the case when err_handler raises HTTPError. # # NOTE(kgriffs): Coverage is giving false negatives, # so disabled on relevant lines. All paths are tested # afaict. try: responder(req, resp, **params) # pragma: no cover except Exception as ex: for err_type, err_handler in self._error_handlers: if isinstance(ex, err_type): err_handler(ex, req, resp, params) break # pragma: no cover else: # PERF(kgriffs): This will propagate HTTPError to # the handler below. It makes handling HTTPError # less efficient, but that is OK since error cases # don't need to be as fast as the happy path, and # indeed, should perhaps be slower to create # backpressure on clients that are issuing bad # requests. raise except HTTPError as ex: helpers.compose_error_response(req, resp, ex) # # Set status and headers # use_body = not helpers.should_ignore_body(resp.status, req.method) if use_body: helpers.set_content_length(resp) body = helpers.get_body(resp, env.get('wsgi.file_wrapper')) else: # Default: return an empty body body = [] # Set content type if needed use_content_type = (body or req.method == 'HEAD' or resp.status == HTTP_416) if use_content_type: media_type = self._media_type else: media_type = None headers = resp._wsgi_headers(media_type) # Return the response per the WSGI spec start_response(resp.status, headers) return body