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

New 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.

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.

exhaust()

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

Changed in version 2.3: Return the remaining data.

Changelog

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

Return type:

bytes

property is_exhausted: bool

Whether the current stream position has reached the limit.

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.

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

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.

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

readable()

Return whether object was opened for reading.

If False, read() will raise OSError.

Return type:

bool

readall()

Read until EOF, using multiple read() call.

Return type:

bytes

tell()

Return the current stream position.

Changelog

New in version 0.9.

Return type:

int

werkzeug.wsgi.make_line_iter(stream, limit=None, buffer_size=10240, cap_at_buffer=False)

Safely iterates line-based over an input stream. If the input stream is not a LimitedStream the limit parameter is mandatory.

This uses the stream’s read() method internally as opposite to the readline() method that is unsafe and can only be used in violation of the WSGI specification. The same problem applies to the __iter__ function of the input stream which calls readline() without arguments.

If you need line-by-line processing it’s strongly recommended to iterate over the input stream using this helper function.

Deprecated since version 2.3: Will be removed in Werkzeug 3.0.

Changelog

New in version 0.11: added support for the cap_at_buffer parameter.

New in version 0.9: added support for iterators as input stream.

Changed in version 0.8: This function now ensures that the limit was reached.

Parameters:
  • stream (Iterable[bytes] | IO[bytes]) – the stream or iterate to iterate over.

  • limit (int | None) – the limit in bytes for the stream. (Usually content length. Not necessary if the stream is a LimitedStream.

  • buffer_size (int) – The optional buffer size.

  • cap_at_buffer (bool) – if this is set chunks are split if they are longer than the buffer size. Internally this is implemented that the buffer size might be exhausted by a factor of two however.

Return type:

Iterator[bytes]

werkzeug.wsgi.make_chunk_iter(stream, separator, limit=None, buffer_size=10240, cap_at_buffer=False)

Works like make_line_iter() but accepts a separator which divides chunks. If you want newline based processing you should use make_line_iter() instead as it supports arbitrary newline markers.

Deprecated since version 2.3: Will be removed in Werkzeug 3.0.

Changelog

Changed in version 0.11: added support for the cap_at_buffer parameter.

Changed in version 0.9: added support for iterators as input stream.

New in version 0.8.

Parameters:
  • stream (Iterable[bytes] | IO[bytes]) – the stream or iterate to iterate over.

  • separator (bytes) – the separator that divides chunks.

  • limit (int | None) – the limit in bytes for the stream. (Usually content length. Not necessary if the stream is otherwise already limited).

  • buffer_size (int) – The optional buffer size.

  • cap_at_buffer (bool) – if this is set chunks are split if they are longer than the buffer size. Internally this is implemented that the buffer size might be exhausted by a factor of two however.

Return type:

Iterator[bytes]

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

New 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

New 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]

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.

Changelog

New 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) – 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

New 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.