def force_type(cls, response, environ=None): """Enforce that the WSGI response is a response object of the current type. Werkzeug will use the `BaseResponse` internally in many situations like the exceptions. If you call `get_response` on an exception you will get back a regular `BaseResponse` object, even if you are using a custom subclass. This method can enforce a given response type, and it will also convert arbitrary WSGI callables into response objects if an environ is provided:: # convert a Werkzeug response object into an instance of the # MyResponseClass subclass. response = MyResponseClass.force_type(response) # convert any WSGI application into a response object response = MyResponseClass.force_type(response, environ) This is especially useful if you want to post-process responses in the main dispatcher and use functionality provided by your subclass. Keep in mind that this will modify response objects in place if possible! """ if not isinstance(response, BaseResponse): if environ is None: raise TypeError('cannot convert WSGI application into ' 'response objects without an environ') response = BaseResponse(*run_wsgi_app(response, environ)) response.__class__ = cls return response
def from_app(cls, app, environ, buffered=False): """Create a new response object from an application output. This works best if you pass it an application that returns a generator 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. """ return cls(*run_wsgi_app(app, environ, buffered))
def from_app(cls, app, environ, buffered=False): """ Create a new response object from an application output. This works best if you pass it an application that returns a generator 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. """ return cls(*run_wsgi_app(app, environ, buffered))
def open(self, path='/', base_url=None, query_string=None, method='GET', data=None, input_stream=None, content_type=None, content_length=0, errors_stream=None, multithread=False, multiprocess=False, run_once=False, environ_overrides=None): """ Open a page for the application. This function takes similar arguments as the `create_environ` method from the utils module. If the first argument is an environ or request object it is used as the environment for the request. """ if input_stream is None and data and method in ('PUT', 'POST'): need_multipart = False if isinstance(data, basestring): assert content_type is not None, 'content type required' else: for key, value in data.iteritems(): if isinstance(value, basestring): if isinstance(value, unicode): data[key] = str(value) continue need_multipart = True if isinstance(value, tuple): data[key] = File(*value) elif isinstance(value, dict): data[key] = File(**value) elif not isinstance(value, File): data[key] = File(value) if need_multipart: boundary, data = encode_multipart(data) if content_type is None: content_type = 'multipart/form-data; boundary=' + \ boundary else: data = urlencode(data) if content_type is None: content_type = 'application/x-www-form-urlencoded' content_length = len(data) input_stream = StringIO(data) if hasattr(path, 'environ'): environ = path.environ elif isinstance(path, dict): environ = path else: environ = create_environ(path, base_url, query_string, method, input_stream, content_type, content_length, errors_stream, multithread, multiprocess, run_once) if environ_overrides: environ.update(environ_overrides) rv = run_wsgi_app(self.application, environ) return self.response_wrapper(*rv)
def open(self, path='/', base_url=None, query_string=None, method='GET', data=None, input_stream=None, content_type=None, content_length=0, errors_stream=None, multithread=False, multiprocess=False, run_once=False, environ_overrides=None, as_tuple=False, buffered=False): """Takes the same arguments as the `create_environ` function from the utility module with some additions. The first parameter should be the path of the request which defaults to '/'. The second one can either be a absolute path (in that case the url host is localhost:80) or a full path to the request with scheme, netloc port and the path to the script. If the `path` contains a query string it will be used, even if the `query_string` parameter was given. If it does not contain one the `query_string` parameter is used as querystring. In that case it can either be a dict, MultiDict or string. The following options exist: `method` The request method. Defaults to `GET` `input_stream` The input stream. Defaults to an empty read only stream. `data` The data you want to transmit. You can set this to a string and define a content type instead of specifying an input stream. Additionally you can pass a dict with the form data. The values could then be strings (no unicode objects!) which are then url encoded or file objects. A file object for this method is either a file descriptor with an additional `name` attribute (like a file descriptor returned by the `open` / `file` function), a tuple in the form ``(fd, filename, mimetype)`` (all arguments except fd optional) or as dict with those keys and values. Additionally you can instanciate the `werkzeug.test.File` object (or a subclass of it) and pass it as value. `content_type` The content type for this request. Default is an empty content type. `content_length` The value for the content length header. Defaults to 0. `errors_stream` The wsgi.errors stream. Defaults to `sys.stderr`. `multithread` The multithreaded flag for the WSGI Environment. Defaults to `False`. `multiprocess` The multiprocess flag for the WSGI Environment. Defaults to `False`. `run_once` The run_once flag for the WSGI Environment. Defaults to `False`. `buffered` Set this to true to buffer the application run. This will automatically close the application for you as well. """ if input_stream is None and data is not None and method in ('PUT', 'POST'): need_multipart = False if isinstance(data, basestring): assert content_type is not None, 'content type required' else: for key, value in data.iteritems(): if isinstance(value, basestring): if isinstance(value, unicode): data[key] = str(value) continue need_multipart = True if isinstance(value, tuple): data[key] = File(*value) elif isinstance(value, dict): data[key] = File(**value) elif not isinstance(value, File): data[key] = File(value) if need_multipart: boundary, data = encode_multipart(data) if content_type is None: content_type = 'multipart/form-data; boundary=' + \ boundary else: data = urlencode(data) if content_type is None: content_type = 'application/x-www-form-urlencoded' content_length = len(data) input_stream = StringIO(data) if hasattr(path, 'environ'): environ = path.environ elif isinstance(path, dict): environ = path else: environ = create_environ(path, base_url, query_string, method, input_stream, content_type, content_length, errors_stream, multithread, multiprocess, run_once) if environ_overrides: environ.update(environ_overrides) rv = run_wsgi_app(self.application, environ, buffered=buffered) response = self.response_wrapper(*rv) if as_tuple: return environ, response return response
def run_app(app, path='/'): env = create_environ(path, SECRET_KEY) return run_wsgi_app(app, env)
def open(self, *args, **kwargs): """Takes the same arguments as the :class:`EnvironBuilder` class with some additions: You can provide a :class:`EnvironBuilder` or a WSGI environment as only argument instead of the :class:`EnvironBuilder` arguments and two optional keyword arguments (`as_tuple`, `buffered`) that change the type of the return value or the way the application is executed. .. versionchanged:: 0.5 If a dict is provided as file in the dict for the `data` parameter the content type has to be called `content_type` now instead of `mimetype`. This change was made for consistency with :class:`werkzeug.FileWrapper`. The `follow_redirects` parameter was added to :func:`open`. Additional parameters: :param as_tuple: Returns a tuple in the form ``(environ, result)`` :param buffered: Set this to true to buffer the application run. This will automatically close the application for you as well. :param follow_redirects: Set this to True if the `Client` should follow HTTP redirects. """ as_tuple = kwargs.pop('as_tuple', False) buffered = kwargs.pop('buffered', False) follow_redirects = kwargs.pop('follow_redirects', False) environ = None if not kwargs and len(args) == 1: if isinstance(args[0], EnvironBuilder): environ = args[0].get_environ() elif isinstance(args[0], dict): environ = args[0] if environ is None: builder = EnvironBuilder(*args, **kwargs) try: environ = builder.get_environ() finally: builder.close() if self.cookie_jar is not None: self.cookie_jar.inject_wsgi(environ) rv = run_wsgi_app(self.application, environ, buffered=buffered) if self.cookie_jar is not None: self.cookie_jar.extract_wsgi(environ, rv[2]) # handle redirects redirect_chain = [] status_code = int(rv[1].split(None, 1)[0]) while status_code in (301, 302, 303, 305, 307) and follow_redirects: redirect = dict(rv[2])['Location'] host = get_host(create_environ('/', redirect)) if get_host(environ).split(':', 1)[0] != host: raise RuntimeError('%r does not support redirect to ' 'external targets' % self.__class__) scheme, netloc, script_root, qs, anchor = urlparse.urlsplit(redirect) redirect_chain.append((redirect, status_code)) kwargs.update({ 'base_url': urlparse.urlunsplit((scheme, host, script_root, '', '')).rstrip('/') + '/', 'query_string': qs, 'as_tuple': as_tuple, 'buffered': buffered, 'follow_redirects': False }) rv = self.open(*args, **kwargs) status_code = int(rv[1].split(None, 1)[0]) # Prevent loops if redirect_chain[-1] in redirect_chain[0:-1]: break response = self.response_wrapper(*rv) if as_tuple: return environ, response return response