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 yieldsbuffer_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 thedirect_passthrough
mode.
- 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 theContent-Length
header value orRequest.max_content_length
.When attempting to read after the limit has been reached,
on_exhausted()
is called. When the limit is a maximum, this raisesRequestEntityTooLarge
.If reading from the stream returns zero bytes or raises an error,
on_disconnect()
is called, which raisesClientDisconnected
. 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 orrequest.max_content_length
.is_max (bool) – Whether the given
limit
isrequest.max_content_length
instead of theContent-Length
header value. This changes how exhausted and disconnect events are handled.
Changelog
Changed in version 2.3: Handle
max_content_length
differently thanContent-Length
.Changed in version 2.3: Implements
io.RawIOBase
rather thanio.IOBase
.- 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:
- 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
toTrue
.More information about file wrappers are available in PEP 333.
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, thenSERVER_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 aSecurityError
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:
- werkzeug.wsgi.get_content_length(environ)¶
Return the
Content-Length
header value as an int. If the header is not given or theTransfer-Encoding
header ischunked
,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 ormax_content_length
.If
Content-Length
exceedsmax_content_length
, aRequestEntityTooLarge`
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 ifwsgi.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 setswsgi.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:
- werkzeug.wsgi.host_is_trusted(hostname, trusted_list)¶
Check if a host matches a list of trusted names.
- Parameters:
- Return type:
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.
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.