All Versions
Latest Version
Avg Release Cycle
70 days
Latest Release

Changelog History
Page 1

  • v2.1.0 Changes

    ๐Ÿš€ Unreleased

    • ๐Ÿ‘ Drop support for Python 3.6. :pr:2277
    • Using gevent or eventlet requires greenlet>=1.0 or PyPy>=7.3.7. werkzeug.locals and contextvars will not work correctly with older versions. :pr:2278
    • ๐Ÿšš Remove previously deprecated code. :pr:2276

      • Remove the non-standard shutdown function from the WSGI environ when running the development server. See the docs for alternatives.
      • Request and response mixins have all been merged into the Request and Response classes.
      • The user agent parser and the useragents module is removed. The user_agent module provides an interface that can be subclassed to add a parser, such as ua-parser. By default it only stores the whole string.
      • The test client returns TestResponse instances and can no longer be treated as a tuple. All data is available as properties on the response.
      • Remove locals.get_ident and related thread-local code from locals, it no longer makes sense when moving to a contextvars-based implementation.
      • Remove the python -m werkzeug.serving CLI.
      • The has_key method on some mapping datastructures; use key in data instead.
      • Request.disable_data_descriptor is removed, pass shallow=True instead.
      • Remove the no_etag parameter from Response.freeze().
      • Remove the HTTPException.wrap class method.
      • Remove the cookie_date function. Use http_date instead.
      • Remove the pbkdf2_hex, pbkdf2_bin, and safe_str_cmp functions. Use equivalents in hashlib and hmac modules instead.
      • Remove the Href class.
      • Remove the HTMLBuilder class.
      • Remove the invalidate_cached_property function. Use del obj.attr instead.
      • Remove bind_arguments and validate_arguments. Use :meth:Signature.bind and :func:inspect.signature instead.
      • Remove detect_utf_encoding, it's built-in to json.loads.
      • Remove format_string, use :class:string.Template instead.
      • Remove escape and unescape. Use MarkupSafe instead.
    • Rely on :pep:538 and :pep:540 to handle decoding file names with the correct filesystem encoding. The filesystem module is removed. :issue:1760

    • 0๏ธโƒฃ Default values passed to Headers are validated the same way values added later are. :issue:1608

    • Setting CacheControl int properties, such as max_age, will convert the value to an int. :issue:2230

    • Always use socket.fromfd when restarting the dev server. :pr:2287

    • ๐Ÿ— When passing a dict of URL values to, list values do not filter out None or collapse to a single value. Passing a MultiDict does collapse single items. This undoes a previous change that made it difficult to pass a list, or None values in a list, to custom URL converters. :issue:2249

    • run_simple shows instructions for dealing with "address already in use" errors, including extra instructions for macOS. :pr:2321

    • Extend list of characters considered always safe in URLs based on :rfc:3986. :issue:2319

    • โšก๏ธ Optimize the stat reloader to avoid watching unnecessary files in more cases. The watchdog reloader is still recommended for performance and accuracy. :issue:2141

    • The development server uses Transfer-Encoding: chunked for streaming responses when it is configured for HTTP/1.1. :issue:2090, 1327, :pr:2091

    • The development server uses HTTP/1.1, which enables keep-alive connections and chunked streaming responses, when threaded or processes is enabled. :pr:2323

    • cached_property works for classes with __slots__ if a corresponding _cache_{name} slot is added. :pr:2332

    • ๐Ÿ”จ Refactor the debugger traceback formatter to use Python's built-in traceback module as much as possible. :issue:1753

    • โœ… The TestResponse.text property is a shortcut for r.get_data(as_text=True), for convenient testing against text instead of bytes. :pr:2337

    • safe_join ensures that the path remains relative if the trusted directory is the empty string. :pr:2349

  • v2.0.3 Changes

    ๐Ÿš€ Released 2022-02-07

    • ๐Ÿ‘ ProxyFix supports IPv6 addresses. :issue:2262
    • Type annotation for Response.make_conditional, HTTPException.get_response, and Map.bind_to_environ accepts Request in addition to WSGIEnvironment for the first parameter. :pr:2290
    • Fix type annotation for Request.user_agent_class. :issue:2273
    • Accessing LocalProxy.__class__ and __doc__ on an unbound proxy returns the fallback value instead of a method object. :issue:2188
    • Redirects with the test client set RAW_URI and REQUEST_URI correctly. :issue:2151
  • v2.0.2 Changes

    ๐Ÿš€ Released 2021-10-05

    • Handle multiple tokens in Connection header when routing WebSocket requests. :issue:2131
    • ๐Ÿ“Œ Set the debugger pin cookie secure flag when on https. :pr:2150
    • โšก๏ธ Fix type annotation for MultiDict.update to accept iterable values :pr:2142
    • ๐Ÿ”€ Prevent double encoding of redirect URL when merge_slash=True for Rule.match. :issue:2157
    • CombinedMultiDict.to_dict with flat=False considers all component dicts when building value lists. :issue:2189
    • send_file only sets a detected Content-Encoding if as_attachment is disabled to avoid browsers saving decompressed .tar.gz files. :issue:2149
    • Fix type annotations for TypeConversionDict.get to not return an Optional value if both default and type are not None. :issue:2169
    • Fix type annotation for routing rule factories to accept Iterable[RuleFactory] instead of Iterable[Rule] for the rules parameter. :issue:2183
    • Add missing type annotation for FileStorage.__getattr__ :issue:2155
    • ๐Ÿ“Œ The debugger pin cookie is set with SameSite set to Strict instead of None to be compatible with modern browser security. :issue:2156
    • Type annotations use IO[bytes] and IO[str] instead of BinaryIO and TextIO for wider type compatibility. :issue:2130
    • Ad-hoc TLS certs are generated with SAN matching CN. :issue:2158
    • Fix memory usage for locals when using Python 3.6 or pre 0.4.17 greenlet versions. :pr:2212
    • Fix type annotation in CallbackDict, because it is not utilizing a bound TypeVar. :issue:2235
    • Fix setting CSP header options on the response. :pr:2237
    • Fix an issue with with the interactive debugger where lines would not expand on click for very long tracebacks. :pr:2239
    • ๐Ÿ‘ป The interactive debugger handles displaying an exception that does not have a traceback, such as from ProcessPoolExecutor. :issue:2217
  • v2.0.1 Changes

    ๐Ÿš€ Released 2021-05-17

    • Fix type annotation for send_file max_age callable. Don't pass pathlib.Path to max_age. :issue:2119
    • Mark top-level names as exported so type checking understands imports in user projects. :issue:2122
    • Fix some types that weren't available in Python 3.6.0. :issue:2123
    • cached_property is generic over its return type, properties decorated with it report the correct type. :issue:2113
    • ๐Ÿ“œ Fix multipart parsing bug when boundary contains special regex characters. :issue:2125
    • Type checking understands that calling headers.get with a string default will always return a string. :issue:2128
    • If HTTPException.description is not a string, get_description will convert it to a string. :issue:2115
  • v2.0.0 Changes

    ๐Ÿš€ Released 2021-05-11

    • ๐Ÿ‘ Drop support for Python 2 and 3.5. :pr:1693
    • ๐Ÿ—„ Deprecate :func:utils.format_string, use :class:string.Template instead. :issue:1756
    • ๐Ÿ—„ Deprecate :func:utils.bind_arguments and :func:utils.validate_arguments, use :meth:Signature.bind and :func:inspect.signature instead. :issue:1757
    • ๐Ÿ—„ Deprecate :class:utils.HTMLBuilder. :issue:1761
    • ๐Ÿ—„ Deprecate :func:utils.escape and :func:utils.unescape, use MarkupSafe instead. :issue:1758
    • ๐Ÿ—„ Deprecate the undocumented python -m werkzeug.serving CLI. :issue:1834
    • ๐Ÿ—„ Deprecate the environ["werkzeug.server.shutdown"] function that is available when running the development server. :issue:1752
    • ๐Ÿ—„ Deprecate the useragents module and the built-in user agent parser. Use a dedicated parser library instead by subclassing user_agent.UserAgent and setting Request.user_agent_class. :issue:2078
    • ๐Ÿšš Remove the unused, internal posixemulation module. :issue:1759
    • All datetime values are timezone-aware with tzinfo=timezone.utc. This applies to anything using http.parse_date:, .if_modified_since, .if_unmodified_since;, .expires, .last_modified, .retry_after; parse_if_range_header, and When comparing values, the other values must also be aware, or these values must be made naive. When passing parameters or setting attributes, naive values are still assumed to be in UTC. :pr:2040
    • ๐Ÿ”€ Merge all request and response wrapper mixin code into single Request and Response classes. Using the mixin classes is no longer necessary and will show a deprecation warning. Checking isinstance or issubclass against BaseRequest and BaseResponse will show a deprecation warning and check against Request or Response instead. :issue:1963
    • ๐Ÿ‘ JSON support no longer uses simplejson if it's installed. To use another JSON module, override Request.json_module and Response.json_module. :pr:1766
    • Response.get_json() no longer caches the result, and the cache parameter is removed. :issue:1698
    • Response.freeze() generates an ETag header if one is not set. The no_etag parameter (which usually wasn't visible anyway) is no longer used. :issue:1963
    • ๐Ÿ— Add a url_scheme argument to to override the bound scheme. :pr:1721
    • ๐Ÿ— Passing an empty list as a query string parameter to build() won't append an unnecessary ?. Also drop any number of None items in a list. :issue:1992
    • โœ… When passing a Headers object to a test client method or EnvironBuilder, multiple values for a key are joined into one comma separated value. This matches the HTTP spec on multi-value headers. :issue:1655
    • Setting Response.status and status_code uses identical parsing and error checking. :issue:1658, :pr:1728
    • MethodNotAllowed and RequestedRangeNotSatisfiable take a response kwarg, consistent with other HTTP errors. :pr:1748
    • The response generated by :exc:~exceptions.Unauthorized produces one WWW-Authenticate header per value in www_authenticate, rather than joining them into a single value, to improve interoperability with browsers and other clients. :pr:1755
    • If parse_authorization_header can't decode the header value, it returns None instead of raising a UnicodeDecodeError. :issue:1816
    • The debugger no longer uses jQuery. :issue:1807
    • โœ… The test client includes the query string in REQUEST_URI and RAW_URI. :issue:1781
    • Switch the parameter order of default_stream_factory to match the order used when calling it. :pr:1085
    • Add send_file function to generate a response that serves a file. Adapted from Flask's implementation. :issue:265, :pr:1850
    • Add send_from_directory function to safely serve an untrusted path within a trusted directory. Adapted from Flask's implementation. :issue:1880
    • send_file takes download_name, which is passed even if as_attachment=False by using Content-Disposition: inline. download_name replaces Flask's attachment_filename. :issue:1869
    • send_file sets conditional=True and max_age=None by default. Cache-Control is set to no-cache if max_age is not set, otherwise public. This tells browsers to validate conditional requests instead of using a timed cache. max_age=None replaces Flask's cache_timeout=43200. :issue:1882
    • send_file can be called with etag="string" to set a custom ETag instead of generating one. etag replaces Flask's add_etags. :issue:1868
    • send_file sets the Content-Encoding header if an encoding is returned when guessing mimetype from download_name. :pr:3896
    • Update the defaults used by generate_password_hash. Increase PBKDF2 iterations to 260000 from 150000. Increase salt length to 16 from 8. Use secrets module to generate salt. :pr:1935
    • The reloader doesn't crash if sys.stdin is somehow None. :pr:1915
    • Add arguments to delete_cookie to match set_cookie and the attributes modern browsers expect. :pr:1889
    • ๐Ÿ—„ utils.cookie_date is deprecated, use utils.http_date instead. The value for Set-Cookie expires is no longer "-" delimited. :pr:2040
    • Use request.headers instead of request.environ to look up header attributes. :pr:1808
    • โœ… The test Client request methods (client.get, etc.) always return an instance of TestResponse. In addition to the normal behavior of Response, this class provides request with the request that produced the response, and history to track intermediate responses when follow_redirects is used. :issue:763, 1894
    • โœ… The test Client request methods takes an auth parameter to add an Authorization header. It can be an Authorization object or a (username, password) tuple for Basic auth. :pr:1809
    • โœ… Calling response.close() on a response from the test Client will close the request input stream. This matches file behavior and can prevent a ResourceWarning in some cases. :issue:1785
    • EnvironBuilder.from_environ decodes values encoded for WSGI, to avoid double encoding the new values. :pr:1959
    • 0๏ธโƒฃ The default stat reloader will watch Python files under non-system/virtualenv sys.path entries, which should contain most user code. It will also watch all Python files under directories given in extra_files. :pr:1945
    • The reloader ignores __pycache__ directories again. :pr:1945
    • run_simple takes exclude_patterns a list of fnmatch patterns that will not be scanned by the reloader. :issue:1333
    • Cookie names are no longer unquoted. This was against :rfc:6265 and potentially allowed setting __Secure prefixed cookies. :pr:1965
    • Fix some word matches for user agent platform when the word can be a substring. :issue:1923
    • ๐Ÿ”Š The development server logs ignored SSL errors. :pr:1967
    • Temporary files for form data are opened in rb+ instead of wb+ mode for better compatibility with some libraries. :issue:1961
    • ๐Ÿ“Œ Use SHA-1 instead of MD5 for generating ETags and the debugger pin, and in some tests. MD5 is not available in some environments, such as FIPS 140. This may invalidate some caches since the ETag will be different. :issue:1897
    • Add Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy response header properties. :pr:2008
    • run_simple tries to show a valid IP address when binding to all addresses, instead of or ::. It also warns about not running the development server in production in this case. :issue:1964
    • ๐ŸŒฒ Colors in the development server log are displayed if Colorama is installed on Windows. For all platforms, style support no longer requires Click. :issue:1832
    • A range request for an empty file (or other data with length 0) will return a 200 response with the empty file instead of a 416 error. :issue:1937
    • New sans-IO base classes for Request and Response have been extracted to contain all the behavior that is not WSGI or IO dependent. These are not a public API, they are part of an ongoing refactor to let ASGI frameworks use Werkzeug. :pr:2005
    • ๐Ÿ”จ Parsing multipart/form-data has been refactored to use sans-io patterns. This should also make parsing forms with large binary file uploads significantly faster. :issue:1788, 875
    • LocalProxy matches the current Python data model special methods, including all r-ops, in-place ops, and async. __class__ is proxied, so the proxy will look like the object in more cases, including isinstance. Use issubclass(type(obj), LocalProxy) to check if an object is actually a proxy. :issue:1754
    • Local uses ContextVar on Python 3.7+ instead of threading.local. :pr:1778
    • request.values does not include form for GET requests (even though GET bodies are undefined). This prevents bad caching proxies from caching form data instead of query strings. :pr:2037
    • The development server adds the underlying socket to environ as werkzeug.socket. This is non-standard and specific to the dev server, other servers may expose this under their own key. It is useful for handling a WebSocket upgrade request. :issue:2052
    • โฌ†๏ธ URL matching assumes websocket=True mode for WebSocket upgrade requests. :issue:2052
    • โšก๏ธ Updated UserAgentParser to handle more cases. :issue:1971
    • werzeug.DechunkedInput.readinto will not read beyond the size of the buffer. :issue:2021
    • Fix connection reset when exceeding max content size. :pr:2051
    • pbkdf2_hex, pbkdf2_bin, and safe_str_cmp are deprecated. hashlib and hmac provide equivalents. :pr:2083
    • invalidate_cached_property is deprecated. Use del instead. :pr:2084
    • ๐Ÿ—„ Href is deprecated. Use werkzeug.routing instead. :pr:2085
    • Request.disable_data_descriptor is deprecated. Create the request with shallow=True instead. :pr:2085
    • ๐Ÿ—„ HTTPException.wrap is deprecated. Create a subclass manually instead. :pr:2085
  • v1.0.2 Changes

    ๐Ÿš€ Unreleased

    • ๐Ÿ“œ Add new "edg" identifier for Edge in UserAgentPreparser. :issue:1797
    • โฌ†๏ธ Upgrade the debugger to jQuery 3.5.1. :issue:1802
  • v1.0.1 Changes

    March 31, 2020

    ๐Ÿš€ Released 2020-03-31

    • Make the argument to RequestRedirect.get_response optional. :issue:1718
    • Only allow a single access control allow origin value. :pr:1723
    • ๐Ÿ”’ Fix crash when trying to parse a non-existent Content Security Policy header. :pr:1731
    • http_date zero fills years < 1000 to always output four digits. :issue:1739
    • Fix missing local variables in interactive debugger console. :issue:1746
    • Fix passing file-like objects like io.BytesIO to :issue:1733
  • v1.0.0 Changes

    February 06, 2020

    ๐Ÿš€ Released 2020-02-06

    • ๐Ÿ‘ Drop support for Python 3.4. (:issue:1478)
    • ๐Ÿšš Remove code that issued deprecation warnings in version 0.15. (:issue:1477)
    • ๐Ÿšš Remove most top-level attributes provided by the werkzeug module in favor of direct imports. For example, instead of import werkzeug; werkzeug.url_quote, do from werkzeug.urls import url_quote. Install version 0.16 first to see deprecation warnings while upgrading. :issue:2, :pr:1640
    • Added utils.invalidate_cached_property() to invalidate cached properties. (:pr:1474)
    • Directive keys for the Set-Cookie response header are not ignored when parsing the Cookie request header. This allows cookies with names such as "expires" and "version". (:issue:1495)
    • ๐Ÿ“œ Request cookies are parsed into a MultiDict to capture all values for cookies with the same key. cookies[key] returns the first value rather than the last. Use cookies.getlist(key) to get all values. parse_cookie also defaults to a MultiDict. :issue:1562, :pr:1458
    • ๐Ÿ‘ป Add charset=utf-8 to an HTTP exception response's CONTENT_TYPE header. (:pr:1526)
    • The interactive debugger handles outer variables in nested scopes such as lambdas and comprehensions. :issue:913, :issue:1037, :pr:1532
    • The user agent for Opera 60 on Mac is correctly reported as "opera" instead of "chrome". :issue:1556
    • The platform for Crosswalk on Android is correctly reported as "android" instead of "chromeos". (:pr:1572)
    • โš  Issue a warning when the current server name does not match the configured server name. :issue:760
    • ๐Ÿ”ง A configured server name with the default port for a scheme will match the current server name without the port if the current scheme matches. :pr:1584
    • :exc:~exceptions.InternalServerError has a original_exception attribute that frameworks can use to track the original cause of the error. :pr:1590
    • โœ… Headers are tested for equality independent of the header key case, such that X-Foo is the same as x-foo. :pr:1605
    • :meth:http.dump_cookie accepts 'None' as a value for samesite. :issue:1549
    • โœ… :meth:~test.Client.set_cookie accepts a samesite argument. :pr:1705
    • ๐Ÿ”’ Support the Content Security Policy header through the Response.content_security_policy data structure. :pr:1617
    • LanguageAccept will fall back to matching "en" for "en-US" or "en-US" for "en" to better support clients or translations that only match at the primary language tag. :issue:450, :pr:1507
    • MIMEAccept uses MIME parameters for specificity when matching. :issue:458, :pr:1574
    • If the development server is started with an SSLContext configured to verify client certificates, the certificate in PEM format will be available as environ["SSL_CLIENT_CERT"]. :pr:1469
    • is_resource_modified will run for methods other than GET and HEAD, rather than always returning False. :issue:409
    • SharedDataMiddleware returns 404 rather than 500 when trying to access a directory instead of a file with the package loader. The dependency on setuptools and pkg_resources is removed. :issue:1599
    • Add a response.cache_control.immutable flag. Keep in mind that browser support for this Cache-Control header option is still experimental and may not be implemented. :issue:1185
    • ๐ŸŒฒ Optional request log highlighting with the development server is handled by Click instead of termcolor. :issue:1235
    • ๐Ÿ‘ Optional ad-hoc TLS support for the development server is handled by cryptography instead of pyOpenSSL. :pr:1555
    • ๐Ÿ‘ supports pathlib and :pep:519 PathLike objects. :issue:1653
    • ๐Ÿ”’ The debugger security pin is unique in containers managed by Podman. :issue:1661
    • ๐Ÿ— Building a URL when host_matching is enabled takes into account the current host when there are duplicate endpoints with different hosts. :issue:488
    • The 429 TooManyRequests and 503 ServiceUnavailable HTTP exceptions takes a retry_after parameter to set the Retry-After header. :issue:1657
    • ๐Ÿ”€ Map and Rule have a merge_slashes option to collapse multiple slashes into one, similar to how many HTTP servers behave. This is enabled by default. :pr:1286, 1694
    • Add HTTP 103, 208, 306, 425, 506, 508, and 511 to the list of status codes. :pr:1678
    • โšก๏ธ Add update, setlist, and setlistdefault methods to the Headers data structure. extend method can take MultiDict and kwargs. :pr:1687, 1697
    • The development server accepts paths that start with two slashes, rather than stripping off the first path segment. :issue:491
    • Add access control (Cross Origin Request Sharing, CORS) header properties to the Request and Response wrappers. :pr:1699
    • Accept values are no longer ordered alphabetically for equal quality tags. Instead the initial order is preserved. :issue:1686
    • Added Map.lock_class attribute for alternative implementations. :pr:1702
    • ๐Ÿ— Support matching and building WebSocket rules in the routing system, for use by async frameworks. :pr:1709
    • Range requests that span an entire file respond with 206 instead of 200, to be more compliant with :rfc:7233. This may help serving media to older browsers. :issue:410, 1704
    • 0๏ธโƒฃ The :class:~middleware.shared_data.SharedDataMiddleware default fallback_mimetype is application/octet-stream. If a filename looks like a text mimetype, the utf-8 charset is added to it. This matches the behavior of :class:~wrappers.BaseResponse and Flask's send_file(). :issue:1689
  • v1.0.0.rc1 Changes

    January 31, 2020

    ๐Ÿš€ Use the --pre flag to install this pre-release:

    pip install --pre Werkzeug==1.0.0rc1
  • v0.16.1 Changes

    January 27, 2020

    ๐Ÿš€ Released 2020-01-27

    • ๐Ÿ“ฆ Fix import location in deprecation messages for subpackages. :issue:1663
    • Fix an SSL error on Python 3.5 when the dev server responds with no content. :issue:1659