WSGI Helpers — Werkzeug Documentation (3.1.x)

# WSGI Helpers

The following classes and functions are designed to make working with the WSGI specification easier or operate on the WSGI layer. All the functionality from this module is available on the high-level Request / Response Objects.

## Iterator / Stream Helpers

These classes and functions simplify working with the WSGI application iterator and the input stream.

class werkzeug.wsgi.ClosingIterator(iterable, callbacks=None)

  The WSGI specification requires that all middlewares and gateways respect the `close` callback of the iterable returned by the application. Because it is useful to add another close action to a returned iterable and adding a custom iterable is a boring task this class can be used for that:

      return ClosingIterator(app(environ, start_response), [cleanup_session,
                                                            cleanup_locals])

  If there is just one close function it can be passed instead of the list.

  A closing iterator is not needed if the application uses response objects and finishes the processing if the response is started:

      try:
          return response(environ, start_response)
      finally:
          cleanup_session()
          cleanup_locals()

  Parameters:

    - iterable (t.Iterable[bytes])

    - callbacks (None | (t.Callable[[], None] | t.Iterable[t.Callable[[], None]]))

class werkzeug.wsgi.FileWrapper(file, buffer_size=8192)

  This class can be used to convert a `file`-like object into an iterable. It yields `buffer_size` blocks until the file is fully read.

  You should not use this class directly but rather use the `wrap_file()` function that uses the WSGI server’s file wrapper support if it’s available.

  Changelog

  Added in version 0.5.

  If you’re using this object together with a `Response` you have to use the `direct_passthrough` mode.

  Parameters:

    - file (t.IO[bytes]) – a `file`-like object with a `read()` method.

    - buffer_size (int) – number of bytes for one iteration.

class werkzeug.wsgi.LimitedStream(stream, limit, is_max=False)

  Wrap a stream so that it doesn’t read more than a given limit. This is used to limit `wsgi.input` to the `Content-Length` header value or `Request.max_content_length`.

  When attempting to read after the limit has been reached, `on_exhausted()` is called. When the limit is a maximum, this raises `RequestEntityTooLarge`.

  If reading from the stream returns zero bytes or raises an error, `on_disconnect()` is called, which raises `ClientDisconnected`. When the limit is a maximum and zero bytes were read, no error is raised, since it may be the end of the stream.

  If the limit is reached before the underlying stream is exhausted (such as a file that is too large, or an infinite stream), the remaining contents of the stream cannot be read safely. Depending on how the server handles this, clients may show a “connection reset” failure instead of seeing the 413 response.

  Parameters:

    - stream (t.IO[bytes]) – The stream to read from. Must be a readable binary IO object.

    - limit (int) – The limit in bytes to not read past. Should be either the `Content-Length` header value or `request.max_content_length`.

    - is_max (bool) – Whether the given `limit` is `request.max_content_length` instead of the `Content-Length` header value. This changes how exhausted and disconnect events are handled.

  Changelog

  Changed in version 2.3: Handle `max_content_length` differently than `Content-Length`.

  Changed in version 2.3: Implements `io.RawIOBase` rather than `io.IOBase`.

  property is_exhausted: bool

    Whether the current stream position has reached the limit.

  on_exhausted()

    Called when attempting to read after the limit has been reached.

    The default behavior is to do nothing, unless the limit is a maximum, in which case it raises `RequestEntityTooLarge`.

    Changelog

    Changed in version 2.3: Raises `RequestEntityTooLarge` if the limit is a maximum.

    Changed in version 2.3: Any return value is ignored.

    Return type:

      None

  on_disconnect(error=None)

    Called when an attempted read receives zero bytes before the limit was reached. This indicates that the client disconnected before sending the full request body.

    The default behavior is to raise `ClientDisconnected`, unless the limit is a maximum and no error was raised.

    Changelog

    Changed in version 2.3: Added the `error` parameter. Do nothing if the limit is a maximum and no error was raised.

    Changed in version 2.3: Any return value is ignored.

    Parameters:

      error (Exception | None)

    Return type:

      None

  exhaust()

    Exhaust the stream by reading until the limit is reached or the client disconnects, returning the remaining data.

    Changelog

    Changed in version 2.3: Return the remaining data.

    Changed in version 2.2.3: Handle case where wrapped stream returns fewer bytes than requested.

    Return type:

      bytes

  readall()

    Read until EOF, using multiple read() call.

    Return type:

      bytes

  tell()

    Return the current stream position.

    Changelog

    Added in version 0.9.

    Return type:

      int

  readable()

    Return whether object was opened for reading.

    If False, read() will raise OSError.

    Return type:

      bool

werkzeug.wsgi.wrap_file(environ, file, buffer_size=8192)

  Wraps a file. This uses the WSGI server’s file wrapper if available or otherwise the generic `FileWrapper`.

  Changelog

  Added in version 0.5.

  If the file wrapper from the WSGI server is used it’s important to not iterate over it from inside the application but to pass it through unchanged. If you want to pass out a file wrapper inside a response object you have to set `Response.direct_passthrough` to `True`.

  More information about file wrappers are available in PEP 333.

  Parameters:

    - file (t.IO[bytes]) – a `file`-like object with a `read()` method.

    - buffer_size (int) – number of bytes for one iteration.

    - environ (WSGIEnvironment)

  Return type:

    t.Iterable[bytes]

## Environ Helpers

These functions operate on the WSGI environment. They extract useful information or perform common manipulations:

werkzeug.wsgi.get_host(environ, trusted_hosts=None)

  Return the host for the given WSGI environment.

  The `Host` header is preferred, then `SERVER_NAME` if it’s not set. The returned host will only contain the port if it is different than the standard port for the protocol.

  Optionally, verify that the host is trusted using `host_is_trusted()` and raise a `SecurityError` if it is not.

  Parameters:

    - environ (WSGIEnvironment) – A WSGI environment dict.

    - trusted_hosts (t.Iterable[str] | None) – A list of trusted host names.

  Returns:

    Host, with port if necessary.

  Raises:

    SecurityError – If the host is not trusted.

  Return type:

    str

werkzeug.wsgi.get_content_length(environ)

  Return the `Content-Length` header value as an int. If the header is not given or the `Transfer-Encoding` header is `chunked`, `None` is returned to indicate a streaming request. If the value is not an integer, or negative, 0 is returned.

  Parameters:

    environ (WSGIEnvironment) – The WSGI environ to get the content length from.

  Return type:

    int | None

  Changelog

  Added in version 0.9.

werkzeug.wsgi.get_input_stream(environ, safe_fallback=True, max_content_length=None)

  Return the WSGI input stream, wrapped so that it may be read safely without going past the `Content-Length` header value or `max_content_length`.

  If `Content-Length` exceeds `max_content_length`, a `RequestEntityTooLarge`` `413 Content Too Large` error is raised.

  If the WSGI server sets `environ["wsgi.input_terminated"]`, it indicates that the server handles terminating the stream, so it is safe to read directly. For example, a server that knows how to handle chunked requests safely would set this.

  If `max_content_length` is set, it can be enforced on streams if `wsgi.input_terminated` is set. Otherwise, an empty stream is returned unless the user explicitly disables this safe fallback.

  If the limit is reached before the underlying stream is exhausted (such as a file that is too large, or an infinite stream), the remaining contents of the stream cannot be read safely. Depending on how the server handles this, clients may show a “connection reset” failure instead of seeing the 413 response.

  Parameters:

    - environ (WSGIEnvironment) – The WSGI environ containing the stream.

    - safe_fallback (bool) – Return an empty stream when `Content-Length` is not set. Disabling this allows infinite streams, which can be a denial-of-service risk.

    - max_content_length (int | None) – The maximum length that content-length or streaming requests may not exceed.

  Return type:

    t.IO[bytes]

  Changelog

  Changed in version 2.3.2: `max_content_length` is only applied to streaming requests if the server sets `wsgi.input_terminated`.

  Changed in version 2.3: Check `max_content_length` and raise an error if it is exceeded.

  Added in version 0.9.

werkzeug.wsgi.get_current_url(environ, root_only=False, strip_querystring=False, host_only=False, trusted_hosts=None)

  Recreate the URL for a request from the parts in a WSGI environment.

  The URL is an IRI, not a URI, so it may contain Unicode characters. Use `iri_to_uri()` to convert it to ASCII.

  Parameters:

    - environ (WSGIEnvironment) – The WSGI environment to get the URL parts from.

    - root_only (bool) – Only build the root path, don’t include the remaining path or query string.

    - strip_querystring (bool) – Don’t include the query string.

    - host_only (bool) – Only build the scheme and host.

    - trusted_hosts (t.Iterable[str] | None) – A list of trusted host names to validate the host against.

  Return type:

    str

werkzeug.wsgi.host_is_trusted(hostname, trusted_list)

  Check if a host matches a list of trusted names.

  Parameters:

    - hostname (str | None) – The name to check.

    - trusted_list (Iterable[str]) – A list of valid names to match. If a name starts with a dot it will match all subdomains.

  Return type:

    bool

  Changelog

  Added in version 0.9.

## Convenience Helpers

werkzeug.wsgi.responder(f)

  Marks a function as responder. Decorate a function with it and it will automatically call the return value as WSGI application.

  Example:

      @responder
      def application(environ, start_response):
          return Response('Hello World!')

  Parameters:

    f (t.Callable[..., WSGIApplication])

  Return type:

    WSGIApplication

werkzeug.testapp.test_app(req)

  Simple test application that dumps the environment. You can use it to check if Werkzeug is working properly:

      >>> from werkzeug.serving import run_simple
      >>> from werkzeug.testapp import test_app
      >>> run_simple('localhost', 3000, test_app)
       * Running on http://localhost:3000/

  The application displays important information from the WSGI environment, the Python interpreter and the installed libraries.

  Parameters:

    req (Request)

  Return type:

    Response

## Bytes, Strings, and Encodings

The values in HTTP requests come in as bytes representing (or encoded to) ASCII. The WSGI specification (PEP 3333) decided to always use the `str` type to represent values. To accomplish this, the raw bytes are decoded using the ISO-8859-1 charset to produce a string.

Strings in the WSGI environment are restricted to ISO-8859-1 code points. If a string read from the environment might contain characters outside that charset, it must first be decoded to bytes as ISO-8859-1, then encoded to a string using the proper charset (typically UTF-8). The reverse is done when writing to the environ. This is known as the “WSGI encoding dance”.

Werkzeug provides functions to deal with this automatically so that you don’t need to be aware of the inner workings. Use the functions on this page as well as `EnvironHeaders()` to read data out of the WSGI environment.

Applications should avoid manually creating or modifying a WSGI environment unless they take care of the proper encoding or decoding step. All high level interfaces in Werkzeug will apply the encoding and decoding as necessary.

## Raw Request URI and Path Encoding

The `PATH_INFO` in the environ is the path value after percent-decoding. For example, the raw path `/hello%2fworld` would show up from the WSGI server to Werkzeug as `/hello/world`. This loses the information that the slash was a raw character as opposed to a path separator.

The WSGI specification (PEP 3333) does not provide a way to get the original value, so it is impossible to route some types of data in the path. The most compatible way to work around this is to send problematic data in the query string instead of the path.

However, many WSGI servers add a non-standard environ key with the raw path. To match this behavior, Werkzeug’s test client and development server will add the raw value to both the `REQUEST_URI` and `RAW_URI` keys. If you want to route based on this value, you can use middleware to replace `PATH_INFO` in the environ before it reaches the application. However, keep in mind that these keys are non-standard and not guaranteed to be present.