def run_wsgi_app(app, environ, buffered=False): """Return a tuple in the form (app_iter, status, headers) of the application output. This works best if you pass it an application that returns an iterator all the time. Sometimes applications may use the `write()` callable returned by the `start_response` function. This tries to resolve such edge cases automatically. But if you don't get the expected output you should set `buffered` to `True` which enforces buffering. If passed an invalid WSGI application the behavior of this function is undefined. Never pass non-conforming WSGI applications to this function. :param app: the application to execute. :param buffered: set to `True` to enforce buffering. :return: tuple in the form ``(app_iter, status, headers)`` """ environ = _get_environ(environ) response = [] buffer = [] def start_response(status, headers, exc_info=None): if exc_info is not None: raise exc_info[0], exc_info[1], exc_info[2] response[:] = [status, headers] return buffer.append app_iter = app(environ, start_response) # when buffering we emit the close call early and convert the # application iterator into a regular list if buffered: close_func = getattr(app_iter, 'close', None) try: app_iter = list(app_iter) finally: if close_func is not None: close_func() # otherwise we iterate the application iter until we have # a response, chain the already received data with the already # collected data and wrap it in a new `ClosingIterator` if # we have a close callable. else: while not response: buffer.append(app_iter.next()) if buffer: close_func = getattr(app_iter, 'close', None) app_iter = chain(buffer, app_iter) if close_func is not None: app_iter = ClosingIterator(app_iter, close_func) return app_iter, response[0], response[1]
def get_response(self, environ): """Get a response object. :param environ: the environ for the request. :return: a :class:`BaseResponse` object or a subclass thereof. """ # lazily imported for various reasons. For one, we can use the exceptions # with custom responses (testing exception instances against types) and # so we don't ever have to import the wrappers, but also because there # are circular dependencies when bootstrapping the module. environ = _get_environ(environ) from wrappers import BaseResponse headers = self.get_headers(environ) return BaseResponse(self.get_body(environ), self.code, headers)
def get_description(self, environ): """Get the description.""" environ = _get_environ(environ) return self.description