NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3426 most downloaded on PyPI
The ultra-reliable, fast ASGI+WSGI framework for building data plane APIs at scale.
Last release 4 days ago
30 Sep 2026
Release timing varies
gaps range from 8 days to 13 months
Some releases are documented
notes for 22 of 38 stable releases
Nothing withdrawn
no release was ever pulled
14 years old
104 releases · first in 2013
Falcon 4.4.0 contains a handful of long-requested features – a RegexConverter field converter, an application-wide error reporter , and a new allow_mu
Falcon 4.4.0 contains a handful of long-requested features – a RegexConverter field converter, an application-wide error reporter, and a new allow_multiple keyword argument for the query string parameter helpers, along with a number of bug fixes. As usual, the newest CPython runtime, 3.15, is fully supported (including binary wheels).
🐍 Falcon 4.4.0 on PyPI
📚 Changelog on RtD
The error reporter also serves as groundwork for the native OpenTelemetry integration that has been on our roadmap for a while. We are hoping to ship that integration as part of Falcon 4.5.
This release would not have been possible without the prototypes, fixes, and feature pull requests submitted by our community. Sincere thanks to our supporters and contributors!
One column per quarter.
This release contains a handful of long-requested features -- a ~falcon.routing.RegexConverter field converter, an application-wide error reporter, and a new allow_multiple keyword argument for the query string parameter helpers, along with a number of bug fixes. As usual, the newest CPython runtime, 3.15, is fully supported (including binary wheels).
The error reporter also serves as groundwork for the native OpenTelemetry integration that has been on our roadmap for a while. We are hoping to ship that integration as part of Falcon 4.5.
This release would not have been possible without the prototypes, fixes, and feature pull requests submitted by our community. Sincere thanks to our supporters and contributors!
CPython 3.15 is now fully supported. (#2593)
A new built-in field converter, ~falcon.routing.RegexConverter, has been added to support regex-based path variable matching. (#857)
A new ~falcon.App method, ~falcon.App.set_error_reporter, was added for observing all exceptions raised while processing requests (for instance, in order to log them, or to submit them to an error tracking or observability service). Error reporters are supported by both WSGI and ASGI applications. (#1942)
Previously, it was not possible to cleanly test the case where a WebSocket responder would keep running without sending or receiving any messages -- ASGIConductor.simulate_ws would hang forever upon exiting the context.
To afford this scenario, a new optional timeout keyword argument was added to ~falcon.testing.ASGIConductor.simulate_ws that limits how long the test harness waits, both for the handshake (accept or deny), and for the app's task to complete after the connection is closed; when the deadline passes, an instance of TimeoutError is raised. (#2585)
An optional allow_multiple keyword argument was added to the query string parameter helpers (~falcon.Request.get_param, ~falcon.Request.get_param_as_bool, ~falcon.Request.get_param_as_date, ~falcon.Request.get_param_as_datetime, ~falcon.Request.get_param_as_dict, ~falcon.Request.get_param_as_float, ~falcon.Request.get_param_as_int, ~falcon.Request.get_param_as_json, ~falcon.Request.get_param_as_media, and ~falcon.Request.get_param_as_uuid).
When it is set to False, and the parameter resolves to more than one value, an ~falcon.HTTPInvalidParam error is raised instead of picking an arbitrary one of those values (default True). (#2735)
As prescribed by PEP 3333, WSGI servers tunnel non-ASCII characters in the request path via ISO-8859-1, and Falcon has long decoded PATH_INFO back to UTF-8. The SCRIPT_NAME variable was, however, used verbatim when populating req.root_path. This has been fixed, and the tunneled SCRIPT_NAME is now decoded in the same way as the request path. (#2667)
When decoding with unquote_plus=False, the cythonized variant of falcon.uri.decode mistook a literal plus sign followed by two hexadecimal digits for a percent-encoded byte. This has been fixed, and a literal plus is now preserved just like in the pure-Python case. (#2670)
When a route was only served by a catch-all on_request() responder, with no HTTP methods explicitly mapped via on_get(), on_post(), etc., the default OPTIONS responder rendered an empty Allow header, misleadingly indicating that the resource allows no methods at all. The Allow header is now omitted when the list of allowed methods is empty. (#2671)
When a simulated ASGI request bubbled up an unhandled exception, the test client's lifespan task was left pending, emitting a stray "Task was destroyed but it is pending!" warning upon garbage collection. Such orphaned lifespan tasks are now cancelled cleanly. (#2745)
Many thanks to all of our talented and stylish contributors for this release!
This is the first release candidate of Falcon 4.4.0.
This is the first release candidate of Falcon 4.4.0.
We would greatly appreciate it if you could help us with testing on your apps!
Let us know if you run into any issues!
🐍 4.4.0rc1 on PyPI
📚 Changelog on RtD
As always, you can grab this pre-release from PyPI:
pip install falcon==4.4.0rc1
Thank You!
This is a SemVer patch release that makes Falcon’s own test suite compatible with the recently released cbor2 6.x series.
This is a SemVer patch release that makes Falcon’s own test suite compatible with the recently released cbor2 6.x series.
🐍 Falcon 4.3.1 on PyPI
📚 Changelog on RtD
Documentation and tests aside, this release is functionally identical to Falcon 4.3.0.
This is a SemVer patch release that makes Falcon's own test suite compatible with the recently released cbor2 6.x series.
Documentation and tests aside, this release is functionally identical to Falcon 4.3.0.
Falcon's test suite is now compatible with the cbor2 6.x series, whose CBORDecodeError is no longer a subclass of ValueError. This is a test-only change with no impact on Falcon's runtime behavior (Falcon has zero hard dependencies outside of the standard library, and cbor2 is only used in our own test suite). (#2663)
Falcon 4.3.0 centers on request parsing and typing enhancements.
Falcon 4.3.0 centers on request parsing and typing enhancements.
🐍 Falcon 4.3.0 on PyPI
📚 Changelog on RtD
On the parsing side, this release introduces a family of new Request methods for extracting structured data from the query string – get_param_as_dict(), get_param_as_media(), and get_query_string_as_media() – together with a new delimiter argument for get_param_as_list(). Several of these align with OpenAPI v3 (and 3.2) parameter styles, making it easier to implement spec-compliant APIs on top of Falcon.
On the typing side, our internal annotations are now strict enough for the project to pass mypy --strict falcon/, and generic App types are now automatically parametrized by the default request/response types on CPython 3.13+.
This release also brings a number of smaller improvements, including MessagePack support in the test client, an opt-in on_request() default responder, and hardening of falcon.secure_filename() against Windows reserved device names.
Two features that we had hoped to land in 4.3 – response teardown callbacks and a native OpenTelemetry integration – did not make the cut in time. Both are now at the top of our priority list for Falcon 4.4.
On the security front, our GitHub Actions workflows are now audited with zizmor, and we have hardened the existing workflows to address the issues it surfaced. Thanks to @woodruffw for maintaining this excellent tool!
This release also incorporates many pull requests submitted by our community. Sincere thanks to all 19 contributors who made this release possible!
Falcon 4.3.0 centers on request parsing and typing. On the parsing side, this release introduces a family of new Request methods for extracting structured data from the query string – get_param_as_dict() , get_param_as_media() , and get_query_string_as_media() – together with a new delimiter argument for get_param_as_list() . Several of these align with OpenAPI v3 (and 3.2) parameter styles, making it easier to implement spec-compliant APIs on top of Falcon.
On the typing side, our internal annotations are now strict enough for the project to pass mypy --strict falcon/ , and generic App types are now automatically parametrized by the default request/response types on CPython 3.13+.
This release also brings a number of smaller improvements, including MessagePack support in the test client, an opt-in on_request() default responder, and hardening of falcon.secure_filename() against Windows reserved device names.
Two features that we had hoped to land in 4.3 – response teardown callbacks and a native OpenTelemetry integration – did not make the cut in time. Both are now at the top of our priority list for Falcon 4.4 .
On the security front, our GitHub Actions workflows are now audited with zizmor , and we have hardened the existing workflows to address the issues it surfaced.
This release also incorporates many pull requests submitted by our community. Sincere thanks to all 19 contributors who made this release possible!
The test client ( simulate_request() and friends) now accepts a msgpack keyword argument, analogous to the existing json one. When provided, the value is serialized as a MessagePack document and used as the request body, and the Content-Type header is set to MEDIA_MSGPACK . ( #1026 )
A new router option, default_to_on_request , was added to allow resources to provide a default responder via on_request() (disabled by default). When enabled, on_request() is used as the default responder for every HTTP method that lacks an explicit responder, except OPTIONS (served by on_options() ) and the special WebSocket handler ( on_websocket() ).
When the option is disabled, or the on_request() method is not implemented, the default responder for "405 Method Not Allowed" is used. ( #2071 )
On Windows, falcon.secure_filename() now escapes reserved device names ( CON , NUL , COM1 , etc.) by prefixing the sanitized value with an underscore. ( #2422 )
Internal type annotations were improved, allowing the project to pass mypy --strict falcon/ . We have added a few # type: ignore comments for known limitations, and are actively working to reduce their necessity. ( #2504 )
The get_param_as_list() method now supports a new argument, delimiter , for splitting values. In line with the OpenAPI v3 parameter specification, the supported delimiters currently include the 'pipeDelimited' and 'spaceDelimited' symbolic constants, as well as the literal ',' , '|' , and ' ' characters. ( #2538 )
A new get_param_as_dict() method was added to Request that retrieves a query parameter as a dict . Two input formats are supported: an alternating key/value list (e.g. param=k1,v1,k2,v2 ) and, when deep_object is set, the OpenAPI v3 deepObject style (e.g. param[k1]=v1¶m[k2]=v2 ). ( #2542 )
A new get_query_string_as_media() method was added to Request . The method URL-decodes the entire query string and deserializes it using the configured media handlers. This is useful for implementing the OpenAPI 3.2 querystring parameter location , where the entire query string is treated as a single serialized value. ( #2546 )
A new get_param_as_media() method was added to Request . It deserializes a single query-string parameter using the configured media handlers, and accepts an optional media_type that falls back to the app’s default_media_type when unspecified. ( #2549 )
A new request property, req.last_event_id , was added to provide convenient access to the Last-Event-ID header. This header is commonly sent by clients when reconnecting to a Server-Sent Events stream. ( #2580 )
Generic App types are now automatically parametrized by the default request/response types (unless specified otherwise), courtesy of TypeVar ’s default value support on CPython 3.13+. ( #2586 )
Due to differences in interpretation of the ASGI specification, Uvicorn could set client in the HTTP connection scope in a way that broke req.access_route and req.remote_addr when the app server was bound to a Unix domain socket.
This discrepancy was addressed, and Falcon should now fall back to the same default value ( '127.0.0.1' ) in this case as if client was missing altogether. ( #2583 )
Documented the US-ASCII restriction on the name and value arguments of falcon.Response.set_cookie() . The implementation has always rejected non-ASCII inputs (raising KeyError for name and ValueError for value ), but the parameter and Raises entries did not call this out; the docstring now matches the runtime behaviour. ( #1445 )
The falcon.testing.redirected() context manager has been deprecated in favor of the standard library’s contextlib.redirect_stdout() and contextlib.redirect_stderr() . It is scheduled for removal in Falcon 5.0. ( #2569 )
Falcon no longer adds an instance of logging.NullHandler to the falcon logger, so ASGI application tracebacks may now reach sys.stderr via the logging.lastResort handler in the absence of configuration (see also: Debugging ASGI Applications ). ( #2594 )
falcon.sys (an internal re-export of the standard library’s sys module that was added inadvertently long ago) is scheduled for removal in Falcon 5.0. Import the standard library’s sys module directly instead. ( #2630 )
Our GitHub Actions workflows are now audited with zizmor , a static analysis tool that catches common security pitfalls in CI/CD pipelines. The audit runs both as a dedicated workflow and as part of our tox checks, and the existing workflows were hardened to address the issues it surfaced. ( #2651 )
Many thanks to all of our talented and stylish contributors for this release!
0x1618
0xMattB
arthurprioli
CaselIT
CuriousHet
gespyrop
granuels
jap
MannXo
mvanhorn
ReinerBRO
rushevich
StepanUFL
tang-vu
thisisrick25
toroleapinc
tuanaiseo
TudorGR
vytas7
On this page
This is the first release candidate of Falcon 4.3.
This is the first release candidate of Falcon 4.3.
If you haven't tested 4.3.0b1 (functionally these two pre-releases are identical) yet, take this release candidate for a spin with your apps, and let us know if you run into any issues (be it runtime, or type-checking)!
🐍 4.3.0rc1 on PyPI
📚 Changelog on RtD
As always, you can grab this pre-release from PyPI:
pip install falcon==4.3.0rc1
Thank You!
This is the first beta release of Falcon 4.3.
This is the first beta release of Falcon 4.3.
We would really be thankful if you could take it for a spin with your apps, and let us know if you run into any troubles (be it runtime, or type-checking)!
🐍 4.3.0b1 on PyPI
📚 Changelog on RtD
As always, you can grab this pre-release from PyPI:
pip install falcon==4.3.0b1
Thank You!
This is the first alpha release of Falcon 4.3.0 . 🐍 4.3.0a1 on PyPI
This is the first alpha release of Falcon 4.3.0.
🐍 4.3.0a1 on PyPI
Note that the final scope of 4.3.0 features will be defined in the first beta. Stay tuned!
Falcon 4.2.0 primarily contains typing enhancements and performance optimizations. This release also marks the debut of pre-compiled wheels for the fr
Falcon 4.2.0 primarily contains typing enhancements and performance optimizations. This release also marks the debut of pre-compiled wheels for the free-threaded CPython 3.14 build. Let us know if you are experimenting with scaling Falcon applications using free-threading!
🐍 Falcon 4.2.0 on PyPI
📚 Changelog on RtD
The typing improvements focus on making the WSGI and ASGI App types generic (parametrized by the request and response types). This should make it significantly easier to properly annotate applications that leverage custom request and/or response types.
Additionally, we have fixed a reproducibility issue (thanks to @bmwiedemann from openSUSE for reporting!) in our documentation build process. Regarding packaging Falcon for distributions in general, we would like to remind you of the Packaging Guide that was published with the previous Falcon release (4.1.0). We hope this guide proves useful.
This release also incorporates a number of pull requests submitted by our community. Sincere thanks to all 8 contributors who made this release possible!
Falcon 4.2.0 primarily contains typing enhancements and performance optimizations. This release also marks the debut of pre-compiled wheels for the free-threaded CPython 3.14 build. Let us know if you are experimenting with scaling Falcon applications using free-threading!
The typing improvements focus on making the WSGI and ASGI App types generic (parametrized by the request and response types). This should make it significantly easier to properly annotate applications that leverage custom request and/or response types.
Additionally, we have fixed a reproducibility issue (thanks to @bmwiedemann from openSUSE for reporting!) in our documentation build process. Regarding packaging Falcon for distributions in general, we would like to remind you of the /community/packaging that was published with the previous Falcon release (4.1.0). We hope this guide proves useful.
This release also incorporates a number of pull requests submitted by our community. Sincere thanks to all 8 contributors who made this release possible!
The end-of-life Python 3.8 is no longer supported. (#2527)
Although the Falcon 4.x series is only guaranteed to support Python 3.10+, this release still supports the end-of-life Python 3.9 at runtime using the pure Python wheel.
(Note that 3.9 is completely unsupported for new development of Falcon apps, as type checking, building documentation, etc, are likely to fail outright.)
Pre-compiled wheels are no longer provided for the macOS x86_64 (Intel) platform. Falcon will continue to install (from the pure Python wheel) and run on macOS Intel just fine. You can also build the binary from sdist yourself. (#2536)
Pre-compiled wheels are now available for the free-threaded CPython 3.14 build on selected Linux platforms. (See also: faq_free_threading) (#2501)
The URI encoding functions ~falcon.uri.encode, ~falcon.uri.encode_check_escaped, ~falcon.uri.encode_value, and ~falcon.uri.encode_value_check_escaped have been reimplemented in Cython, leading to a significant speed bump under CPython (provided Falcon is installed from a binary wheel, or cythonized from a source distribution).
The performance improvement can reach an order of magnitude, although the actual numbers vary depending on the input data. For instance, on CPython 3.12, calling ~falcon.uri.encode_value with 'no-reply@falconframework.org' would be sped up ~9x, and using the already encoded value 'no-reply%40falconframework.org' with ~falcon.uri.encode_value_check_escaped could yield a ~12x speed boost. (#1169)
falcon.App and falcon.asgi.App have been converted to generic types parametrized by the request and response types, and popular type checkers such as Mypy and Pyright should now correctly infer the use of custom subclasses passed by request_type and response_type, respectively. (#2372)
Falcon now supports the retrieval-like QUERY HTTP method; handlers can be implemented using on_query(req, resp, ...) on resources. See the IETF draft for details: https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-11.html. (#2539)
Falcon's documentation build process was not fully reproducible, as the output could vary with the build system's date. The issue was addressed by adding support for setting the build date via the SOURCE_DATE_EPOCH standardized environment variable. (#2567)
Many thanks to all of our talented and stylish contributors for this release!
This is the first release candidate of Falcon 4.2.0.
This is the first release candidate of Falcon 4.2.0.
We would greatly appreciate it if you could help us with testing on your apps!
If you use type checking, please also check how the new generic App types (and other typing improvements) work for you.
Let us know if you run into any issues!
🐍 4.2.0rc1 on PyPI
📚 Changelog on RtD
As always, you can grab this pre-release from PyPI:
pip install falcon==4.2.0rc1
Thank You!
This release contains enhancements to media handling, serving static files, and a fix for the WebSockets-sink interaction, alongside performance optim
This release contains enhancements to media handling, serving static files, and a fix for the WebSockets-sink interaction, alongside performance optimizations and full support for CPython 3.14.
🐍 Falcon 4.1.0 on PyPI
📚 Changelog on RtD
During this release cycle, we have migrated to publishing to PyPI with a Trusted Publisher (thanks to @webknjaz for helping to iron out the workflow details).
For those relying on other package distribution channels than PyPI, we have prepared a brand new Packaging Guide for Falcon. Please check it out and let us know what you think! Additionally, we have formalized our security maintenance policy as well as the status of stable releases: Releases and Versioning.
This release also incorporates many pull requests submitted by our community. We would like to extend our heartfelt thanks to all 17 contributors who made this release possible!
This release contains enhancements to media handling, serving static files, and a fix for the WebSockets-sink interaction, alongside performance optimizations and full support for CPython 3.14.
During this release cycle, we have migrated to publishing to PyPI with a Trusted Publisher (thanks to @webknjaz for helping to iron out the workflow details).
For those relying on other package distribution channels than PyPI, we have prepared a brand new /community/packaging for Falcon. Please check it out and let us know what you think! Additionally, we have formalized our security maintenance policy as well as the status of stable releases: /community/releases.
This release also incorporates many pull requests submitted by our community. We would like to extend our heartfelt thanks to all 17 contributors who made this release possible!
CPython 3.14 is now fully supported. (#2413)
Although the Falcon 4.x series is only guaranteed to support Python 3.10+, this release still supports 3.8 & 3.9 at runtime using the pure Python wheel.
Falcon 4.2 is expected to drop the end-of-life Python 3.8 completely (but runtime support will continue for 3.9 on a best effort basis).
~falcon.routing.StaticRoute now renders Etag headers. It also checks If-None-Match in requests and returns HTTP 304 response if appropriate. (#2243)
~falcon.routing.StaticRoute now sets the Last-Modified header when serving static files. The improved implementation also checks the value of the If-Modified-Since header, and renders an HTTP 304 response when the requested file has not been modified. (#2244)
Similar to ~falcon.testing.create_environ, the ~falcon.testing.create_scope testing helper now preserves the raw URI path, and propagates it to the created ASGI connection scope as the raw_path byte string (according to the ASGI specification). (#2262)
Two new media_type constants, falcon.MEDIA_CSV and falcon.MEDIA_PARQUET, were added in order to provide better support for Python data analysis applications out of the box. (#2335)
Support for allowing cross-origin private network access was added to the built-in ~falcon.middleware.CORSMiddleware. The new feature is off by default, and can be enabled by passing the keyword argument allow_private_network=True to ~falcon.middleware.CORSMiddleware during initialization. (#2381)
The falcon.secure_filename() utility function can now ensure that the length of the sanitized filename does not exceed the requested limit (passed via the max_length argument). In addition, a new option, max_secure_filename_length, was added to ~falcon.media.multipart.MultipartParseOptions in order to automatically populate this argument when referencing a body part's ~falcon.media.multipart.BodyPart.secure_filename. (#2420)
The ~falcon.Response.unset_cookie method now accepts a same_site parameter (with underscore) for consistency with ~falcon.Response.set_cookie. The previous samesite parameter (without underscore) is now deprecated (referencing it will emit a deprecation warning). (#2453)
A new method, __rich__, has been added to falcon.testing.Result for facilitating a rich-text representation when used together with the popular rich library.
Provided you have installed both falcon and rich into your environment, you should be able to see a prettier rendition of the below 404-result:
>>> import falcon
>>> import falcon.testing
>>> import rich.pretty
>>> rich.pretty.install()
>>> client = falcon.testing.TestClient(falcon.App())
>>> client.get('/endpoint')
Result<404 Not Found application/json b'{"title": "404 Not Found"}'>
(The actual appearance may depend on your terminal and/or REPL settings.) (#2457)
The cythonization process was revised in the light of the performance improvements in newer CPython versions (especially 3.12+), and the compilation is now largely confined to hand-crafted C/Cython code. As a result, the framework should run even faster on modern CPython. (#2470)
~falcon.media.JSONHandler can now detect a non-standard (not a subclass of ValueError) deserialization error type for a custom loads function.
(Normally, json.loads and third party alternatives do raise a subclass of ValueError on invalid input data, however, this is not the case for, e.g., the popular msgspec library at the time of writing.) (#2476)
Previously, Falcon's WebSocket implementation was not documented to route the request to any sink. However, in the case of a missing route, a matching sink was actually invoked, passing ws in place of the incompatible resp.
This mismatch has been addressed by introducing a ws keyword argument (similar to ASGI error handlers) for sink functions meant to accept WebSocket connections.
For backwards-compatibility, when ws is absent from the sink's signature, the ~falcon.asgi.WebSocket object is still passed in place of the incompatible resp. This behavior will change in Falcon 5.0: when draining a WebSocket connection, resp will always be set to None. (#2414)
The readability of the Contributing docs was improved by properly rendering GitHub Markdown-flavored checkboxes. (#2318)
The falcon.testing.httpnow compatibility alias is now considered deprecated, and will be removed in Falcon 5.0. Use the falcon.http_now function instead. (#2389)
Many thanks to all of our talented and stylish contributors for this release!
This is the first release candidate of Falcon 4.1.0.
This is the first release candidate of Falcon 4.1.0.
We would greatly appreciate it if you could help us with the final round of testing on your apps, and let us know if you run into any issues!
🐍 4.1.0rc1 on PyPI
📚 Changelog on RtD
As always, you can grab this pre-release from PyPI:
pip install falcon==4.1.0rc1
Thank You!
This is the first beta release of Falcon 4.1.
This is the first beta release of Falcon 4.1.
As Falcon 4.1 is now feature-complete, we would really be thankful if you could take it for a spin with your apps, and let us know if you run into any issues!
🐍 4.1.0b1 on PyPI
📚 Changelog on RtD
As always, you can grab this pre-release from PyPI:
pip install falcon==4.1.0b1
Thank You!
This is yet another alpha release for validating the security improvements to the _Trusted Publishing_ workflow. :snake: 4.1.0a3 on PyPI
This is yet another alpha release for validating the security improvements to the Trusted Publishing workflow. :snake: 4.1.0a3 on PyPI
Note that the final scope of 4.1.0 features will be defined in the first beta. Stay tuned!
This is the first published alpha release of Falcon 4.1.0. (4.1.0a1 was not published due to a CI configuration error.) :snake: 4.1.0a2 on PyPI
This is the first published alpha release of Falcon 4.1.0. (4.1.0a1 was not published due to a CI configuration error.)
:snake: 4.1.0a2 on PyPI
This pre-release marks the first time that we are taking advantage of PyPI's Trusted Publishing.
Note that the final scope of 4.1.0 features will be defined in the first beta. Stay tuned!
Falcon 4.0.2 is a minor point release (following the major Falcon 4.0.0 release, and Falcon 4.0.1 bugfix) to fix some missed re-exports for type check
Falcon 4.0.2 is a minor point release (following the major Falcon 4.0.0 release, and Falcon 4.0.1 bugfix) to fix some missed re-exports for type checkers. In addition, we have also included a couple of documentation improvements.
:snake: Falcon 4.0.2 on PyPI
Running Mypy on code that uses parts of falcon.testing would previously lead to errors like:
Name "falcon.testing.TestClient" is not defined
This has been fixed by explicitly exporting the names that are imported into the falcon.testing namespace. (#2387)
The printable PDF version of our documentation was enabled on Read the Docs. (#2365)
This is a minor point release to fix some missed re-exports for type checkers. In addition, we have also included a couple of documentation improvements.
Running Mypy on code that uses parts of falcon.testing would previously lead to errors like:
Name "falcon.testing.TestClient" is not defined
This has been fixed by explicitly exporting the names that are imported into the falcon.testing namespace. (#2387)
The printable PDF version of our documentation was enabled on Read the Docs. (#2365)
Many thanks to those who contributed to this bugfix release:
Falcon 4.0.1 is a minor point release addressing a Python distribution issue in Falcon 4.0.0.
Falcon 4.0.1 is a minor point release addressing a Python distribution issue in Falcon 4.0.0.
Installing Falcon 4.0.0 unexpectedly copies many unintended directories from the source tree to the venv’s site-packages. This issue has been rectified, and our CI has been extended with new tests (that verify what is actually installed from the distribution) to make sure this regression does not resurface. (#2384)
This is a minor point release addressing a Python distribution issue in Falcon 4.0.0.
Installing Falcon 4.0.0 unexpectedly copies many unintended directories from the source tree to the venv's site-packages. This issue has been rectified, and our CI has been extended with new tests (that verify what is actually installed from the distribution) to make sure this regression does not resurface. (#2384)
…shims, as well as made other potentially breaking changes that we could not risk in a minor version. If you have been paying attention the deprecation…
We are happy to present Falcon 4.0, a new major version of the framework that brings a couple of commonly requested features including support for matching multiple path segments (using PathConverter), and a fully typed codebase. (Please read more about typing in the notes on RtD.)
:snake: Falcon 4.0.0 on PyPI :books: Changelog on RtD
The timeframe for Falcon 4.0 was challenging due to the need to balance our high standards with the CPython 3.13 timeline. We aimed to deliver the main development branch in this release, without resorting to another compatibility micro update (as we did with Falcon 3.1.1-3.1.3). Following community feedback, we also want to improve our overall release schedule by shipping smaller increments more often. To support this goal, we have made several tooling and testing improvements: the build process for binary wheels has been simplified using cibuildwheel, and our test suite now only requires pytest as a hard dependency. Additionally, you can run pytest against our tests from any directory. We hope that these changes should also benefit packaging Falcon in Linux distributions.
As with every SemVer major release, we have removed a number of previously deprecated functions, classes, compatibility shims, as well as made other potentially breaking changes that we could not risk in a minor version. If you have been paying attention the deprecation warnings from the 3.x series, the impact should be minimal, but please do take a look at the list of breaking changes on RtD.
This release would not have been possible without the numerous contributions from our community. This release alone comprises a number of pull requests submitted by a group of 30 talented individuals. What is more, we were particularly impressed by the high-quality discussions and code submissions during our EuroPython 2024 Sprint. Some notable sprint contributions include CHIPS support, and a new WebSocket Tutorial, among others. In fact, according to the statistics on GitHub, we are thrilled to report that the total number of Falcon contributors has now exceeded 200. We find it fascinating that our framework has become a collaborative effort involving so many individuals, and would like to thank everyone who has made this release possible!
We are happy to present Falcon 4.0, a new major version of the framework that brings a couple of commonly requested features including support for matching multiple path segments (using ~falcon.routing.PathConverter), and a fully typed codebase. (Please read more about typing in the notes below.)
The timeframe for Falcon 4.0 was challenging due to the need to balance our high standards with the CPython 3.13 timeline. We aimed to deliver the main development branch in this release, without resorting to another compatibility micro update (as we did with Falcon 3.1.1-3.1.3). Following community feedback, we also want to improve our overall release schedule by shipping smaller increments more often. To support this goal, we have made several tooling and testing improvements: the build process for binary wheels has been simplified using cibuildwheel, and our test suite now only requires pytest as a hard dependency. Additionally, you can run pytest against our tests from any directory. We hope that these changes should also benefit packaging Falcon in Linux distributions.
As with every SemVer major release, we have removed a number of previously deprecated functions, classes, compatibility shims, as well as made other potentially breaking changes that we could not risk in a minor version. If you have been paying attention the deprecation warnings from the 3.x series, the impact should be minimal, but please do take a look at the list of breaking changes below.
This release would not have been possible without the numerous contributions from our community. This release alone comprises a number of pull requests submitted by a group of 30 talented individuals. What is more, we were particularly impressed by the high-quality discussions and code submissions during our EuroPython 2024 Sprint. Some notable sprint contributions include CHIPS support, and a new WebSocket Tutorial, among others. In fact, according to the statistics on GitHub, we are thrilled to report that the total number of Falcon contributors has now exceeded 200. We find it fascinating that our framework has become a collaborative effort involving so many individuals, and would like to thank everyone who has made this release possible!
CPython 3.11 is now fully supported. (#2072)
CPython 3.12 is now fully supported. (#2196)
CPython 3.13 is now fully supported. (#2258)
End-of-life Python 3.5, 3.6 & 3.7 are no longer supported. (#2074, #2273)
End-of-life Python 3.8 is no longer actively supported, but the framework should still continue to install from the pure-Python wheel or source distribution, and function normally.
The Falcon 4.x series is guaranteed to support CPython 3.10 and PyPy3.10 (v7.3.16). This means that we may drop the support for Python 3.8 & 3.9 altogether in a later 4.x release, especially if we are faced with incompatible ecosystem changes in typing, Cython, etc.
Type checking support was introduced in version 4.0. While most of the library is now typed, further type annotations may be added throughout the 4.x release cycle. To improve them, we may introduce changes to the typing that do not affect runtime behavior, but may surface new or different errors with type checkers.
Note
All undocumented type aliases coming from falcon._typing are considered private to the framework itself, and not meant for annotating applications using Falcon. To that end, it is advisable to only use classes from the public interface, and public aliases from falcon.typing, e.g.:
class MyResource:
def on_get(self, req: falcon.Request, resp: falcon.Response) -> None:
resp.media = {'message': 'Hello, World!'}
If you still decide to reuse the private aliases anyway, they should preferably be imported inside if TYPE_CHECKING: blocks in order to avoid possible runtime errors after an update. Also, make sure to let us know which essential aliases are missing from the public interface!
Falcon's emphasis on flexibility and performance has presented certain challenges when it comes to adding type annotations to the existing code base. One notable limitation involves using custom ~falcon.Request and/or ~falcon.Response types in callbacks that are passed back to the framework, such as when adding an error handler.
For instance, the following application might unexpectedly not pass type checking:
from typing import Any
from falcon import App, HTTPInternalServerError, Request, Response
class MyRequest(Request):
...
def handle_os_error(req: MyRequest, resp: Response, ex: Exception,
params: dict[str, Any]) -> None:
raise HTTPInternalServerError(title='OS error!') from ex
app = App(request_type=MyRequest)
app.add_error_handler(OSError, handle_os_error)
(Please also see the following GitHub issue: #2372.)
Important
This is only a typing limitation that has no effect outside of type checking -- the above app will run just fine!
Falcon is no longer vendoring the python-mimeparse library; the relevant functionality has instead been reimplemented in the framework itself, fixing a handful of long-standing bugs in the new implementation.
If you use standalone python-mimeparse in your project, do not worry! We will continue to maintain it as a separate package under the Falconry umbrella (we took over about 3 years ago).
The following new behaviors are considered breaking changes:
Previously, the iterable passed to req.client_prefers had to be sorted in the order of increasing desirability. ~falcon.mediatypes.best_match, and by proxy ~falcon.Request.client_prefers, now consider the provided media types to be sorted in the (more intuitive, we hope) order of decreasing desirability.
Unlike python-mimeparse, the new media type utilities consider media types with different values for the same parameters as non-matching.
One theoretically possible scenario where this change can affect you is only installing a media handler for a content type with parameters; it then may not match media types with conflicting values (that used to match before Falcon 4.0). If this turns out to be the case, also install the same handler for the generic type/subtype without parameters.
The new functions, falcon.mediatypes.quality and falcon.mediatypes.best_match, otherwise have the same signature as the corresponding methods from python-mimeparse. (#864)
A number of undocumented internal helpers were renamed to start with an underscore, indicating they are private methods intended to be used only by the framework itself:
falcon.request_helpers.header_property → falcon.request_helpers._header_property
falcon.request_helpers.parse_cookie_header → falcon.request_helpers._parse_cookie_header
falcon.response_helpers.format_content_disposition → falcon.response_helpers._format_content_disposition
falcon.response_helpers.format_etag_header → falcon.response_helpers._format_etag_header
falcon.response_helpers.format_header_value_list → falcon.response_helpers._format_header_value_list
falcon.response_helpers.format_range → falcon.response_helpers._format_range
falcon.response_helpers.header_property → falcon.response_helpers._header_property
falcon.response_helpers.is_ascii_encodable → falcon.response_helpers._is_ascii_encodable
If you were relying on these internal helpers, you can either copy the implementation into your codebase, or switch to the underscored variants. (Needless to say, though, we strongly recommend against referencing private methods, as we provide no SemVer guarantees for them.) (#1457)
A number of previously deprecated methods, attributes and classes have now been removed:
In Falcon 3.0, the use of positional arguments was deprecated for the optional initializer parameters of falcon.HTTPError and its subclasses.
We have now redefined these optional arguments as keyword-only, so passing them as positional arguments will result in a TypeError:
>>> import falcon
>>> falcon.HTTPForbidden('AccessDenied')
Traceback (most recent call last):
<...>
TypeError: HTTPForbidden.__init__() takes 1 positional argument but 2 were given
>>> falcon.HTTPForbidden('AccessDenied', 'No write access')
Traceback (most recent call last):
<...>
TypeError: HTTPForbidden.__init__() takes 1 positional argument but 3 were given
Instead, simply pass these parameters as keyword arguments:
>>> import falcon >>> falcon.HTTPForbidden(title='AccessDenied') <HTTPForbidden: 403 Forbidden> >>> falcon.HTTPForbidden(title='AccessDenied', description='No write access') <HTTPForbidden: 403 Forbidden>
The falcon-print-routes command-line utility is no longer supported; falcon-inspect-app is a direct replacement.
falcon.stream.BoundedStream is no longer re-imported via falcon.request_helpers. If needed, import it directly as falcon.stream.BoundedStream.
A deprecated alias of falcon.stream.BoundedStream, falcon.stream.Body, was removed. Use falcon.stream.BoundedStream instead.
A deprecated utility function, falcon.get_http_status(), was removed. Please use falcon.code_to_http_status instead.
A deprecated routing utility, compile_uri_template(), was removed. This function was only employed in the early versions of the framework, and is expected to have been fully supplanted by the ~falcon.routing.CompiledRouter. In a pinch, you can simply copy its implementation from the Falcon 3.x source tree into your application.
The deprecated Response.add_link() method was removed; please use Response.append_link instead.
The deprecated has_representation() method for ~falcon.HTTPError was removed, along with the NoRepresentation and OptionalRepresentation classes.
An undocumented, deprecated public method find_by_media_type() of media.Handlers was removed. Apart from configuring handlers for Internet media types, the rest of ~falcon.media.Handlers is only meant to be used internally by the framework (unless documented otherwise).
Previously, the json module could be imported via falcon.util. This deprecated alias was removed; please import json directly from the standard library, or another third-party JSON library of choice.
We decided, on the other hand, to keep the deprecated falcon.API alias until Falcon 5.0. (#1853)
Previously, it was possible to create an ~falcon.App with the cors_enable option, and add additional ~falcon.CORSMiddleware, leading to unexpected behavior and dysfunctional CORS. This combination now explicitly results in a ValueError. (#1977)
The default value of the csv parameter in ~falcon.uri.parse_query_string was changed to False, matching the default behavior of other parts of the framework (such as req.params, the test client, etc). If the old behavior fits your use case better, pass the csv=True keyword argument explicitly. (#1999)
The deprecated api_helpers was removed in favor of the app_helpers module. In addition, the deprecated body attributes of the ~falcon.Response, asgi.Response, and ~falcon.HTTPStatus classes were removed. (#2090)
The function falcon.http_date_to_dt now validates HTTP dates to have the correct timezone set. It now also returns timezone-aware ~datetime.datetime objects. As a consequence of this change, the return value of falcon.Request.get_header_as_datetime (including the derived properties ~falcon.Request.date, ~falcon.Request.if_modified_since, ~falcon.Request.if_unmodified_since, and falcon.testing.Cookie.expires) has also changed to timezone-aware.
Furthermore, the default value of the format_string parameter in falcon.Request.get_param_as_datetime and falcon.routing.DateTimeConverter has also been updated to use a timezone-aware form. (#2182)
setup.cfg was dropped in favor of consolidating all static project configuration in pyproject.toml (setup.py is still needed for programmatic control of the build process). While this change should not impact the framework's end-users directly, some setuptools-based legacy workflows (such as the obsolete setup.py test) will no longer work. (#2314)
The is_async keyword argument was removed from ~falcon.media.validators.jsonschema.validate, as well as the hooks ~falcon.before and ~falcon.after, since it represented a niche use case that is even less relevant with the recent advances in the ecosystem: Cython 3.0+ will now correctly mark cythonized async def functions as coroutines, and pure-Python factory functions that return a coroutine can now be marked as such using inspect.markcoroutinefunction (Python 3.12+ is required). (#2343)
A new keyword argument, link_extension, was added to falcon.Response.append_link as specified in RFC 8288, Section 3.4.2. (#228)
A new path converter capable of matching segments that include / was added. (#648)
The new implementation of media type utilities (Falcon was using the python-mimeparse library before) now always favors the exact media type match, if one is available. (#1367)
Type annotations have been added to Falcon's public interface to the package itself in order to better support Mypy (or other type checkers) users without having to install any third-party typeshed packages. (#1947)
Similar to the existing ~falcon.routing.IntConverter, a new ~falcon.routing.FloatConverter has been added, allowing to convert path segments to float. (#2022)
The default error serializer will now use the response media handlers to better negotiate the response content type with the client. The implementation still defaults to JSON if the client does not indicate any preference. (#2023)
~falcon.asgi.WebSocket now supports providing a reason for closing the socket, either directly via ~falcon.asgi.WebSocket.close or by configuring ~falcon.asgi.WebSocketOptions.default_close_reasons. (#2025)
An informative representation was added to testing.Result for easier development and interpretation of failed tests. The form of __repr__ is as follows: Result<{status_code} {content-type header} {content}>, where the content part will reflect up to 40 bytes of the result's content. (#2044)
A new method falcon.Request.get_header_as_int was implemented. (#2060)
A new property, ~falcon.Request.headers_lower, was added to provide a unified, self-documenting way to get a copy of all request headers with lowercase names to facilitate case-insensitive matching. This is especially useful for middleware components that need to be compatible with both WSGI and ASGI. ~falcon.Request.headers_lower was added in lieu of introducing a breaking change to the WSGI ~falcon.Request.headers property that returns uppercase header names from the WSGI environ dictionary. (#2063)
In Python 3.13, the cgi module is removed entirely from the stdlib, including its parse_header() method. Falcon addresses the issue by shipping an own implementation; falcon.parse_header can also be used in your projects affected by the removal. (#2066)
A new status_code attribute was added to the falcon.Response, falcon.asgi.Response, HTTPStatus, and HTTPError classes. (#2108)
Following the recommendation from RFC 9239, the MEDIA_JS constant has been updated to text/javascript. Furthermore, this and other media type constants are now preferred to the stdlib's mimetypes for the initialization of ~falcon.ResponseOptions.static_media_types. (#2110)
A new keyword argument, samesite, was added to ~falcon.Response.unset_cookie that allows to override the default Lax setting of SameSite on the unset cookie. (#2124)
A new keyword argument, partitioned, was added to ~falcon.Response.set_cookie to opt a cookie into partitioned storage, with a separate cookie jar per each top-level site. (See also CHIPS for a more detailed description of this web technology.) (#2213)
The class falcon.HTTPPayloadTooLarge was renamed to falcon.HTTPContentTooLarge, together with the accompanying HTTP status code update, in order to reflect the newest HTTP semantics as per RFC 9110, Section 15.5.14. (The old class name remains available as a deprecated compatibility alias.)
In addition, one new status code constant was added: falcon.HTTP_421 (also available as falcon.HTTP_MISDIRECTED_REQUEST) in accordance with RFC 9110, Section 15.5.20. (#2276)
The ~falcon.CORSMiddleware now properly handles the missing Allow header case, by denying the preflight CORS request. The static file route has been updated to properly support CORS preflight, by allowing GET requests. (#2325)
Added falcon.testing.Result.content_type and falcon.testing.StreamedResult.content_type as a utility accessor for the Content-Type header. (#2349)
A new flag, ~falcon.ResponseOptions.xml_error_serialization, has been added to ~falcon.ResponseOptions that can be used to disable automatic XML serialization of ~falcon.HTTPError when using the default error serializer (and the client prefers it).
This new flag currently defaults to True, preserving the same behavior as the previous Falcon versions. Falcon 5.0 will either change the default to False, or remove the automatic XML error serialization altogether. If you wish to retain support for XML serialization in the default error serializer, you should add a response media handler for XML.
In accordance with this change, the falcon.HTTPError.to_xml method was deprecated. (#2355)
The web servers used for tests are now run through sys.executable in order to ensure that they respect the virtualenv in which tests are being run. (#2047)
Previously, importing ~falcon.testing.TestCase as a top-level attribute in a test module could make pytest erroneously attempt to collect its methods as test cases. This has now been prevented by adding a __test__ attribute (set to False) to the ~falcon.testing.TestCase class. (#2147)
Falcon will now raise an instance of ~falcon.errors.WebSocketDisconnected from the OSError that the ASGI server signals in the case of a disconnected client (as per the ASGI HTTP & WebSocket protocol version 2.4). It is worth noting though that Falcon's built-in receive buffer normally detects the websocket.disconnect event itself prior the potentially failing attempt to send().
Disabling this built-in receive buffer (by setting ~falcon.asgi.WebSocketOptions.max_receive_queue to 0) was also found to interfere with receiving ASGI WebSocket messages in an unexpected way. The issue has been fixed so that setting this option to 0 now properly bypasses the buffer altogether, and extensive test coverage has been added for validating this scenario. (#2292)
Customizing MultipartParseOptions.media_handlers could previously lead to unintentionally modifying a shared class variable. This has been fixed, and the ~falcon.media.multipart.MultipartParseOptions.media_handlers attribute is now initialized to a fresh copy of handlers for every instance of ~falcon.media.multipart.MultipartParseOptions. To that end, a proper ~falcon.media.Handlers.copy method has been implemented for the media ~falcon.media.Handlers class. (#2293)
Falcon's multipart form parser no longer requires a CRLF ('\r\n') after the closing -- delimiter. Although it is a common convention (followed by the absolute majority of HTTP clients and web browsers) to include a trailing CRLF, the popular Undici client (used as Node's default fetch implementation) omits it at the time of this writing. (The next version of Undici will adhere to the convention.) (#2364)
The utility functions create_task() and get_running_loop() are now deprecated in favor of their standard library counterparts, asyncio.create_task and asyncio.get_running_loop. (#2253)
The falcon.TimezoneGMT class was deprecated. Use the UTC timezone (datetime.timezone.utc) from the standard library instead. (#2301)
Many thanks to all of our talented and stylish contributors for this release!
We are almost ready to release Falcon 4.0! :snake: 4.0.0rc1 on PyPI :books: Changelog on RtD
We are almost ready to release Falcon 4.0! :snake: 4.0.0rc1 on PyPI :books: Changelog on RtD
We would greatly appreciate it if you could help us with the final round of testing on your apps (pip install falcon==4.0.0rc1),
and let us know if you run into any issues!
Thank You!
Compared to `4.0.0b3`, we have made the timezone-aware datetime breaking changes more consistent, and documented the scope clearer.
Falcon 4.0.0b4 is hopefully the final beta release of Falcon 4.0. Compared to 4.0.0b3, we have made the timezone-aware datetime breaking changes more consistent, and documented the scope clearer.
:snake: 4.0.0b4 on PyPI :books: Changelog on RtD
Please test this beta release with your apps (pip install falcon==4.0.0b4), and let us know if you run into any issues!
Thank You!
This is the third beta release of Falcon 4.0; it is almost identical to `4.0.0b2` with the exception of one multipart form parsing bug that has been f
This is the third beta release of Falcon 4.0; it is almost identical to 4.0.0b2 with the exception of one multipart form parsing bug that has been fixed (https://github.com/falconry/falcon/issues/2364).
:snake: 4.0.0b3 on PyPI :books: Changelog on RtD
Please test this beta release with your apps (pip install falcon==4.0.0b3), and let us know if you run into any issues!
Thank You!
…much easier for the developer to track down this breaking change).
This is the second beta release of Falcon 4.0, where we made minor CI tweaks, and brought back the unintentionally removed, blocked resp.body property (it raises an instance of specialized AttributeError instead of a silent failure, making it much easier for the developer to track down this breaking change).
:snake: 4.0.0b2 on PyPI :books: Changelog on RtD
This release is otherwise largely identical to 4.0.0b1.
Please test this beta release with your apps (pip install falcon==4.0.0b2), and let us know if you run into any issues!
Thank You!
The first beta release of Falcon 4.0.0 is here!
The first beta release of Falcon 4.0.0 is here!
Falcon 4.0 is now feature-complete, and we would really be thankful if you could test this beta release with your apps, and let us know if you run into any issues!
If you make use of type annotations in your Falcon app, please run your type checker of choice without any typeshed extensions for Falcon, and report back to us how it went!
:snake: 4.0.0b1 on PyPI :books: Changelog on RtD
As always, you can grab the new release from PyPI:
pip install falcon==4.0.0b1
This release would have not been possible without contributions from the fantastic group of 30 community members and maintainers.
Thank You!
The full changelog of new features, breaking changes and fixes will be rendered as part of the first beta release.
The second alpha release of Falcon 4.0.0 is out!
Although we are still in the process of polishing the last items from the version 4.0 milestone, we do not expect (m)any radical changes from now on until Falcon 4.0.0 final. The full changelog of new features, breaking changes and fixes will be rendered as part of the first beta release.
This release hopefully addresses the build issues we encountered in 4.0.0a1.
We would really appreciate if you could help with early testing on your code!
You can grab this release from PyPI (pip install falcon==4.0.0a2), and let us know how it went!
The full changelog of new features, breaking changes and fixes will be rendered as part of the first beta release.
The first alpha release of Falcon 4.0.0 is here!
Although we are still in the process of polishing the last items from the version 4.0 milestone, we do not expect (m)any radical changes from now on until Falcon 4.0.0 final. The full changelog of new features, breaking changes and fixes will be rendered as part of the first beta release.
One wheel failed to build on Windows, so nothing has been published to PyPI yet :grimacing:. We will address this issue in 4.0.0a2.
If you feel adventurous, you can still build and test the release from the below files here on GitHub:
# Build binaries (takes a couple of minutes)
pip install https://github.com/falconry/falcon/releases/download/4.0.0a1/falcon-4.0.0a1.tar.gz
# Pure-python wheel (fast install, slightly lower runtime performance)
pip install https://github.com/falconry/falcon/releases/download/4.0.0a1/falcon-4.0.0a1-py3-none-any.whl
Falcon 3.1.3 is a minor bugfix release that only pins the pytest-asyncio test dependency in order to prevent an incompatible version from interfering
Falcon 3.1.3 is a minor bugfix release that only pins the pytest-asyncio test dependency
in order to prevent an incompatible version from interfering with the build workflow.
This release is otherwise identical to Falcon 3.1.2.
This is a minor bugfix release that only pins the pytest-asyncio test dependency in order to prevent an incompatible version from interfering with the build workflow.
This release is otherwise identical to Falcon 3.1.2.
Falcon 3.1.3 is a minor bugfix release that only pins the pytest-asyncio test dependency in order to prevent an incompatible version from interfering
Falcon 3.1.3 is a minor bugfix release that only pins the pytest-asyncio test dependency
in order to prevent an incompatible version from interfering with the build workflow.
This release is otherwise identical to Falcon 3.1.2.
Falcon 3.1.2 is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
Falcon 3.1.2 is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
This is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
Falcon is now supported (including binary wheels) on CPython 3.12. A couple of remaining stdlib deprecations from 3.11 and 3.12 will be addressed in Falcon 4.0.
As with the previous release, Python 3.5 & 3.6 remain deprecated and will no longer be supported in Falcon 4.0.
EOL Python 3.7 will no longer be actively supported in 4.0, but the framework should still continue to install from source. We may remove the support for 3.7 altogether later in the 4.x series if we are faced with incompatible ecosystem changes in typing, Cython, etc.
Some essential files were unintentionally omitted from the source distribution archive, rendering it unsuitable to run the test suite off. This has been fixed, and the sdist tarball should now be usable as a base for packaging Falcon in OS distributions. (#2051)
WebSocket implementation has been fixed to properly handle ~falcon.HTTPError and ~falcon.HTTPStatus exceptions raised by custom error handlers. The WebSocket connection is now correctly closed with an appropriate code instead of bubbling up an unhandled error to the application server. (#2146)
Falcon's ~falcon.testing.TestClient mimics the behavior of real WSGI servers (and the WSGI spec) by presenting the PATH_INFO CGI variable already in the percent-decoded form. However, the client also used to indiscriminately set the non-standard RAW_URI CGI variable to /, which made writing tests for apps decoding raw URL path cumbersome. This has been fixed, and the raw path of a simulated request is now preserved in RAW_URI. (#2157)
Many thanks to those who contributed to this bugfix release:
Falcon 3.1.2 is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
Falcon 3.1.2 is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
This is the first release candidate of Falcon 3.1.2.
Falcon 3.1.2 is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
Falcon 3.1.2 is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
This is the second beta release of Falcon 3.1.2.
Falcon 3.1.2 is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
Falcon 3.1.2 is a minor point release fixing a couple of high impact bugs, as well as publishing binary wheels for the recently released CPython 3.12.
This is the first beta release of Falcon 3.1.2.
Falcon 3.1.1 is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
Falcon 3.1.1 is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
This is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
Falcon is now functional on CPython 3.11. Full 3.11 support (including taking care of stdlib deprecations) will be formalized in Falcon 4.0.
As with the previous release, Python 3.5 & 3.6 remain deprecated and will no longer be supported in Falcon 4.0.
Request attributes ~falcon.Request.forwarded_scheme and ~falcon.Request.forwarded_host now no longer raise an IndexError while processing an invalid or empty Forwarded header. (#2043)
The orjson library now works correctly when used as JSON serializer in the media handlers in the ASGI version of Falcon. (#2100)
Many thanks to those who contributed to this bugfix release:
Falcon 3.1.1 is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
Falcon 3.1.1 is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
This is the first release candidate of Falcon 3.1.1.
https://falcon.readthedocs.io/en/3.1.1b3/changes/3.1.1.html
https://falcon.readthedocs.io/en/3.1.1b3/changes/3.1.1.html
b3 attempts to fix a yet another wheel build issue discovered in b2. :sweat_smile:
Falcon 3.1.1 is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
Falcon 3.1.1 is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
b2 attempts to fix a wheel build issue on CPython 3.11 discovered in b1.
Falcon 3.1.1 is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
Falcon 3.1.1 is a minor point release addressing a couple of high impact bugs, and enabling the framework on the recently released CPython 3.11.
This is the first beta release of Falcon 3.1.1.
This release also adds support for CPython 3.10 and deprecates CPython 3.6.
This release contains several refinements to request validation and error handling, along with some tweaks to response handling for static and downloadable files.
Due to popular demand, TestClient and ASGIConductor now expose convenience shorthand aliases for the simulate_* methods, i.e., simulate_get() is now also available as get(), etc.
Some important bugs were also fixed to ensure applications properly clean up response streams and do not hang when reading request bodies that are streamed using chunked transfer encoding.
This release also adds support for CPython 3.10 and deprecates CPython 3.6.
This release contains several refinements to request validation and error handling, along with some tweaks to response handling for static and downloadable files.
Due to popular demand, ~falcon.testing.TestClient and ~falcon.testing.ASGIConductor now expose convenience shorthand aliases for the simulate_* methods, i.e., ~falcon.testing.TestClient.simulate_get is now also available as ~falcon.testing.TestClient.get, etc.
Some important bugs were also fixed to ensure applications properly clean up response streams and do not hang when reading request bodies that are streamed using chunked transfer encoding.
This release also adds support for CPython 3.10 and deprecates CPython 3.6.
CPython 3.10 is now fully supported. (#1966)
Support for Python 3.6 is now deprecated and will be removed in Falcon 4.0.
As with the previous release, Python 3.5 support remains deprecated and will no longer be supported in Falcon 4.0.
The jsonschema.validate decorator now raises an instance of ~falcon.MediaValidationError instead of the generic ~falcon.HTTPBadRequest for request media validation failures. Although the default behavior is kept unaltered in a backwards-compatible fashion (as the specialized exception subclasses the generic one), but it can now be easily customized by adding an error handler for the new class. (#1320)
Due to popular demand, ~falcon.testing.TestClient and ~falcon.testing.ASGIConductor now expose convenience shorthand aliases for the simulate_* methods, i.e., ~falcon.testing.TestClient.simulate_get is now also available as ~falcon.testing.TestClient.get, etc. (#1806)
The Request.range property now has stricter validation:
When parsing a byte-range-spec with a last-byte-pos, it must be greater than or equal to first-byte-pos.
When parsing a suffix-byte-range-spec, suffix-length must be positive.
Static routes now support Range requests. This is useful for streaming media and resumable downloads. (#1858)
Added a Response.viewable_as property; this is similar to Response.downloadable_as but with an "inline" disposition type so the response will still be displayed in the browser. (#1951)
Added support for passing pathlib.Path objects as directory in the ~falcon.App.add_static_route method on all targeted Python versions. (#1962)
Static routes now set the Content-Length header indicating a served file's size (or length of the rendered content range). (#1991)
When called with deprecated positional arguments, methods and class initializers (such as falcon.HTTPError) will now emit a user-friendlier warning indicating the fully qualified name of the method in question. (#2010)
If provided, the close() method of an ASGI resp.stream is now guaranteed to be called even in the case of an exception raised while iterating over the data. (#1943)
Previously, files could be left open when serving via an ASGI static route (depending on the underlying GC implementation). This has been fixed so that a file is closed explicitly after rendering the response. (#1963)
When a request was streamed using the chunked transfer encoding (with no Content-Length known in advance), iterating over req.stream could hang until the client had disconnected. This bug has been fixed, and iteration now stops upon receiving the last body chunk as expected. (#2024)
The ~falcon.routing.compile_uri_template utility method has been deprecated and will be removed in Falcon 4.0. This function was only employed in the early versions of the framework, and is expected to have been fully supplanted by the ~falcon.routing.CompiledRouter. In the unlikely case it is still in active use, its source code can be simply copied into an affected application. (#1967)
Many thanks to all the contributors for this release!
Changes: falcon.readthedocs.io/en/latest/changes/3.1.0.html
Changes: https://falcon.readthedocs.io/en/latest/changes/3.1.0.html
Changes: https://falcon.readthedocs.io/en/latest/changes/3.1.0.html
Nothing published for this version
…removed) without announcing a corresponding breaking change. This module is now considered deprecated, and will be removed in a future Falcon version.
This is a minor point release to take care of a couple of bugs that we did not catch for 3.0.0.
api_helpers module was re-added, since it was renamed to app_helpers (and effectively removed) without announcing a corresponding breaking change. This module is now considered deprecated, and will be removed in a future Falcon version. (#1902)Many thanks to those who contributed to this bugfix release:
This is a minor point release to take care of a couple of bugs that we did not catch for 3.0.0.
The api_helpers module was re-added, since it was renamed to app_helpers (and effectively removed) without announcing a corresponding breaking change. This module is now considered deprecated, and will be removed in a future Falcon version. (#1902)
ASGI HTTP headers were treated as UTF-8 encoded, not taking the incompatibility with WSGI and porting of WSGI applications into consideration. This was fixed, and ASGI headers are now decoded and encoded as ISO-8859-1. (#1911)
Many thanks to those who contributed to this bugfix release:
We are pleased to present Falcon 3.0, a major new release that includes ASGI-based asyncio and WebSocket support, fantastic multipart/form-data parsin
We are pleased to present Falcon 3.0, a major new release that includes ASGI-based asyncio and WebSocket support, fantastic multipart/form-data parsing, better error handling, enhancements to existing features, and the usual assortment of bug fixes.
Thanks to @CaselIT we also now provide native cythonized wheels for common platforms via GitHub Actions!
A sincere thank you to our incredible group of 38 contributors who submitted pull requests for this release, as well as to all those who generously provided financial support to the project. Over the years we like to think that our little framework has had a positive impact on the Python community, and has even helped nudge the state of the art forward. And it is all thanks to our amazing supporters and contributors.
👉 3.0.0 on PyPI 👉 Changelog 👉 multipart/form-data 👉 ASGI Tutorial
We are pleased to present Falcon 3.0, a major new release that includes ASGI-based asyncio and WebSocket support, fantastic multipart/form-data parsing, better error handling, enhancements to existing features, and the usual assortment of bug fixes.
This is easily the biggest release—in terms of both hours volunteered and code contributed—that we have ever done. We sincerely thank our stupendous group of 38 contributors who submitted pull requests for this release, as well as all those who have generously provided financial support to the project.
When we began working on this release, we knew we wanted to not only evolve the framework's existing features, but also to deliver first-class, user-friendly asyncio support alongside our existing WSGI feature set.
On the other hand, we have always fought the temptation to expand Falcon's scope, in order to leave room for community projects and standards to innovate around common, self-contained capabilities. And so when ASGI arrived on the scene, we saw it as the perfect opportunity to deliver long-requested asyncio and WebSocket features while still encouraging sharing and reuse within the Python web community.
It can be painful to migrate a large code base to a major new version of a framework. Therefore, in 3.0 we went to great lengths to minimize breaking changes, although a number of methods and attributes were deprecated. That being said, everyone will likely run up against at least one or two items in the breaking changes list below. Please carefully review the list of changes and thoroughly test your apps with Falcon 3.0 before deploying to production.
Leading up to this release, members of the core maintainers team spent many hours (and not a few late nights and weekends) prototyping, tuning, and testing in order to uphold the high standards of correctness and reliability for which Falcon is known. That being said, no code is perfect, so please don't hesitate to reach out on falconry/user or GitHub if you run into any issues.
Again, thanks so much to everyone who supported this release! Over the years we like to think that our little framework has had a positive impact on the Python community, and has even helped nudge the state of the art forward. And it is all thanks to our amazing supporters and contributors.
Python 3.8 and 3.9 are now fully supported.
Python 3.6+ is only required when using the new ASGI interface. WSGI is still supported on Python 3.5+.
Python 3.5 support is deprecated and may be removed in the next major release.
Python 3.4 is no longer supported.
The Falcon 2.x series was the last to support Python language version 2. As a result, support for CPython 2.7 and PyPy2.7 was removed in Falcon 3.0.
The class ~.falcon.http_error.OptionalRepresentation and the attribute ~.falcon.HTTPError.has_representation were deprecated. The default error serializer now generates a representation for every error type that derives from falcon.HTTPError. In addition, Falcon now ensures that any previously set response body is cleared before handling any raised exception. (#452)
The class ~.falcon.http_error.NoRepresentation was deprecated. All subclasses of falcon.HTTPError now have a media type representation. (#777)
In order to reconcile differences between the framework's support for WSGI vs. ASGI, the following breaking changes were made:
falcon.testing.create_environ previously set a default User-Agent header, when one was not provided, to the value 'curl/7.24.0 (x86_64-apple-darwin12.0)'. As of Falcon 3.0, the default User-Agent string is now f'falcon-client/{falcon.__version__}'. This value can be overridden for the sake of backwards-compatibility by setting falcon.testing.helpers.DEFAULT_UA.
The falcon.testing.create_environ function's protocol keyword argument was renamed to http_version and now only includes the version number (the value is no longer prefixed with 'HTTP/').
The falcon.testing.create_environ function's app keyword argument was renamed to root_path.
The writeable property of falcon.stream.BoundedStream was renamed to writable per the standard file-like I/O interface (the old name was a misspelling)
If an error handler raises an exception type other than falcon.HTTPStatus or falcon.HTTPError, remaining middleware process_response methods will no longer be executed before bubbling up the unhandled exception to the web server.
falcon.get_http_status no longer accepts floats, and the method itself is deprecated.
falcon.app_helpers.prepare_middleware no longer accepts a single object; the value that is passed must be an iterable.
falcon.Request.access_route now includes the value of the ~falcon.Request.remote_addr property as the last element in the route, if not already present in one of the headers that are checked.
When the 'REMOTE_ADDR' field is not present in the WSGI environ, Falcon will assume '127.0.0.1' for the value, rather than simply returning None for falcon.Request.remote_addr.
The changes above were implemented as part of the ASGI+HTTP work stream. (#1358)
Header-related methods of the ~falcon.Response class no longer coerce the passed header name to a string via str(). (#1497)
An unhandled exception will no longer be raised to the web server. Rather, the framework now installs a default error handler for the Exception type. This also means that middleware process_response methods will still be called in this case, rather than being skipped as previously. The new default error handler simply generates an HTTP 500 response. This behavior can be overridden by specifying your own error handler for Exception via ~falcon.API.add_error_handler. (#1507)
Exceptions are now handled by the registered handler for the most specific matching exception class, rather than in reverse order of registration. "Specificity" is determined by the method resolution order of the raised exception type. (See ~falcon.App.add_error_handler for more details.) (#1514)
The deprecated stream_len property was removed from the ~falcon.Response class. Please use ~falcon.Response.set_stream() or ~falcon.Response.content_length instead. (#1517)
If RequestOptions.strip_url_path_trailing_slash is enabled, routes should now be added without a trailing slash. Previously, the trailing slash was always removed as a side effect of a bug regardless of the ~falcon.RequestOptions.strip_url_path_trailing_slash option value. See also: trailing_slash_in_path (#1544)
Rename falcon.Response.body and falcon.HTTPStatus.body to text. The old name is deprecated, but still available. (#1578)
Referencing the class falcon.stream.BoundedStream through the falcon.request_helpers module is deprecated. It is now accessible from the module falcon.stream. (#1583)
General refactoring of internal media handler:
Deserializing an empty body with a handler that does not support it will raise falcon.MediaNotFoundError, and will be rendered as a 400 Bad Request response. This error may be suppressed by passing a default value to get_media to be used in case of empty body. See also falcon.Request.get_media for details. Previously None was returned in all cases without calling the handler.
Exceptions raised by the handlers are wrapped as falcon.MediaMalformedError, and will be rendered as a 400 Bad Request response.
Subsequent calls to falcon.Request.get_media or falcon.Request.media will re-raise the same exception, if the first call ended in an error, unless the exception was a falcon.MediaNotFoundError and a default value is passed to the default_when_empty attribute of the current invocation. Previously None was returned.
External handlers should update their logic to align to the internal Falcon handlers. (#1589)
The falcon.Response.data property now just simply returns the same data object that it was set to, if any, rather than also checking and serializing the value of the falcon.Response.media property. Instead, a new ~falcon.Response.render_body method has been implemented, which can be used to obtain the HTTP response body for the request, taking into account the ~falcon.Response.text, ~falcon.Response.data, and ~falcon.Response.media attributes. (#1679)
The params_csv parameter now defaults to False in falcon.testing.simulate_request. The change was made to match the default value of the request option ~falcon.RequestOptions.auto_parse_qs_csv (False since Falcon 2.0). (#1730)
The falcon.HTTPError.to_json now returns bytes instead of str. Importing json from falcon.util is deprecated. (#1767)
The private attributes for ~.falcon.media.JSONHandler were renamed, and the private attributes used by ~.falcon.media.MessagePackHandler were replaced. Subclasses that refer to these variables will need to be updated. In addition, the undocumented falcon.media.Handlers.find_by_media_type method was deprecated and may be removed in a future release. (#1822)
ASGI+WebSocket support was added to the framework via falcon.asgi.App and falcon.asgi.WebSocket. (#321)
The error classes in falcon.errors were updated to have the title and description keyword arguments and to correctly handle headers passed as list of tuples (#777)
~falcon.media.MultipartFormHandler was added to enable support for multipart forms (of content type multipart/form-data) through falcon.Request.get_media(). (#953)
The falcon.Response.status attribute can now be also set to an http.HTTPStatus instance, an integer status code, as well as anything supported by the falcon.code_to_http_status utility method. (#1135)
A new kwarg, cors_enable, was added to the falcon.App initializer. cors_enable can be used to enable a simple blanket CORS policy for all responses. (See also: cors.) (#1194)
ASGI+HTTP support was added to the framework via a new class, falcon.asgi.App. The testing module was also updated to fully support ASGI apps, including two new helper functions: falcon.testing.create_scope and falcon.testing.create_asgi_req. WSGI users also get a new falcon.testing.create_req method. As part of the ASGI work, several additional utility functions were added, including falcon.is_python_func, falcon.http_status_to_code and falcon.code_to_http_status; as well as sync/async helpers falcon.get_running_loop, falcon.create_task, falcon.sync_to_async, falcon.wrap_sync_to_async, and falcon.wrap_sync_to_async_unsafe. (#1358)
The falcon.App class initializer now supports a new argument sink_before_static_route (default True, maintaining 2.0 behavior) to specify if sinks should be handled before or after static routes. (#1372)
The falcon.Response.append_link method now supports setting the crossorigin link CORS settings attribute. (#1410)
Falcon now supports all WebDAV methods (RFC 2518 and RFC 4918), such as COPY, LOCK, MKCOL, MOVE, PROPFIND, PROPPATCH and UNLOCK. (#1426)
Added inspect module to collect information about an application regarding the registered routes, middleware, static routes, sinks and error handlers (See also: inspect.) (#1435)
WSGI path decoding in falcon.Request was optimized, and is now significantly faster than in Falcon 2.0. (#1492)
The ~falcon.Response.set_headers method now accepts an instance of any dict-like object that implements an items() method. (#1546)
Change falcon.routing.CompiledRouter to compile the routes only when the first request is routed. This can be changed by passing compile=True to falcon.routing.CompiledRouter.add_route. (#1550)
The ~falcon.Response.set_cookie method now supports setting the SameSite cookie attribute. (#1556)
The falcon.API class was renamed to falcon.App. The old API class remains available as an alias for backwards-compatibility, but it is now considered deprecated and will be removed in a future release. (#1579)
~falcon.media.URLEncodedFormHandler was added to enable support for URL-encoded forms (of content type application/x-www-form-urlencoded) through falcon.Request.get_media(). The ~.RequestOptions.auto_parse_form_urlencoded option is now deprecated in favor of ~falcon.media.URLEncodedFormHandler. (See also: access_urlencoded_form). (#1580)
~falcon.Request.get_param_as_bool now supports the use of 't' and 'y' values for True, as well as 'f' and 'n' for False. (#1606)
falcon.testing.simulate_request() now accepts a content_type keyword argument. This provides a more convenient way to set this common header vs. the headers argument. (#1646)
When no route matches a request, the framework will now raise a specialized subclass of ~.falcon.HTTPNotFound (~.falcon.HTTPRouteNotFound) so that a custom error handler can distinguish that specific case if desired. (#1647)
Default media handlers were simplified by removing a separate handler for the now-obsolete application/json; charset=UTF-8. As a result, providing a custom JSON media handler will now unambiguously cover both application/json and the former Content-type. (#1717)
Previously, the default CompiledRouter was erroneously stripping trailing slashes from URI templates. This has been fixed so that it is now possible to add two different routes for a path with and without a trailing forward slash (see also: RequestOptions.strip_url_path_trailing_slash). (#1544)
falcon.uri.decode and falcon.uri.parse_query_string no longer explode quadratically for a large number of percent-encoded characters. The time complexity of these utility functions is now always close to O(n). (#1594)
When ~falcon.RequestOptions.auto_parse_qs_csv is enabled, the framework now correctly parses all occurrences of the same parameter in the query string, rather than only splitting the values in the first occurrence. For example, whereas previously t=1,2&t=3,4 would become ['1', '2', '3,4'], now the resulting list will be ['1', '2', '3', '4'] (#1597)
The ~falcon.uri.parse_query_string() utility function is now correctly parsing an empty string as {}. (#1600)
Previously, response serialization errors (such as in the case of a faulty custom media handler, or because an instance of ~falcon.HTTPUnsupportedMediaType was raised for an unsupported response content type) were unexpectedly bubbled up to the application server. This has been fixed, and these errors are now handled exactly the same way as other exceptions raised in a responder (see also: errors). (#1607)
falcon.Request.forwarded_host now contains the port when proxy headers are not set, to make it possible to correctly reconstruct the URL when the application is not behind a proxy. (#1678)
The Response.downloadable_as property is now correctly encoding non-ASCII filenames as per RFC 6266 recommendations. (#1749)
The falcon.routing.CompiledRouter no longer mistakenly sets route parameters while exploring non matching routes. (#1779)
The ~falcon.to_query_str method now correctly encodes parameter keys and values. As a result, the params parameter in ~falcon.testing.simulate_request will now correctly pass values containing special characters (such as '&') to the application. (#1871)
falcon.uri.encode and falcon.uri.encode_value now escape all percent characters by default even if it appears they have already been escaped. The falcon.uri.encode_check_escaped and falcon.uri.encode_value_check_escaped methods have been added to give the option of retaining the previous behavior where needed. These new methods have been applied to the falcon.Response.location, falcon.Response.content_location, falcon.Response.append_link attrs and methods to retain previous behavior. (#1872)
Previously, methods marked with the ~falcon.deprecated utility wrapper could raise an unexpected AttributeError when running under certain applications servers such as Meinheld. This has been fixed so that ~falcon.deprecated no longer relies on the availability of interpreter-specific stack frame introspection capabilities. (#1882)
Deprecate the use of positional arguments for the optional kw args of the falcon.HTTPError subclasses (#777)
Setup towncrier to make CHANGES reporting much easier. (#1461)
Fix test errors on Windows (#1656)
A new method, ~falcon.Request.get_media, was added that can now be used instead of the falcon.Request.media property to make it more clear to app maintainers that getting the media object for a request involves a side-effect of consuming and deserializing the body stream. The original property remains available to ensure backwards-compatibility with existing apps. (#1679)
Falcon now uses the falcon.Response media handlers when serializing to JSON falcon.HTTPError and falcon.asgi.SSEvent. falcon.Request will use its defined media handler when loading a param as JSON with falcon.Request.get_param_as_json. (#1767)
The add_link() method of the falcon.Request class was renamed to falcon.Response.append_link. The old name is still available as a deprecated alias. (#1801)
Many thanks to all of our talented and stylish contributors for this release!
https://pypi.org/project/falcon/3.0.0rc3
https://pypi.org/project/falcon/3.0.0rc3
rc2 just includes a few documentation tweaks and GH Actions fixes since rc1.
rc2 just includes a few documentation tweaks and GH Actions fixes since rc1.
$ pip install falcon==3.0.0rc2
👉 3.0.0rc2 on PyPI 👉 Changelog 👉 multipart/form-data 👉 ASGI Tutorial
We have completed our final round of performance tuning, bug fixing, and doc improvements for 3.0. From this point on, we will only accept critical bu
We have completed our final round of performance tuning, bug fixing, and doc improvements for 3.0. From this point on, we will only accept critical bug fixes and non-invasive documentation improvements for the final release.
$ pip install falcon==3.0.0rc1
As before, this release includes native wheels with Cython support for Linux, macOS, and Windows.
👉 3.0.0rc1 on PyPI 👉 Changelog 👉 multipart/form-data 👉 ASGI Tutorial
Again, many thanks go out to the talented and well-dressed community members who have contributed to the Falcon 3.0.0 release.
Please try the release candidate with some of your apps, and let us know in falconry/dev if you run into any issues.
We really need all hands on deck to ensure this is a rock-solid release.
Thank you!
We have completed our semi-final round of performance tuning, bug fixing, and doc improvements. From this point on, we will only accept critical bug f
We have completed our semi-final round of performance tuning, bug fixing, and doc improvements. From this point on, we will only accept critical bug fixes and non-invasive documentation improvements for the final release.
$ pip install falcon==3.0.0b2
As before, this release includes native wheels with Cython support for Linux, macOS, and Windows.
👉 3.0.0b2 on PyPI 👉 ASGI Tutorial
Again, many thanks go out to the talented and well-dressed community members who have contributed to the Falcon 3.0.0 release. It has been a long road, and we have very much appreciated everyone's patience and input along the way. Adding features like native ASGI support, lean-and-mean WebSocket handling, and incredibly efficient and robust multipart form parsing, was no easy task. But we wanted to get it right and deliver a well-tested, forward-looking feature set sans hacks and compatibility layers.
Please see RTD for the complete changelog for the next major release of Falcon, and please try out the beta with some of your apps. Let us know in falconry/dev if you run into any issues.
We really need all hands on deck to ensure this is a rock-solid release.
Thank you!
After many, many hours of designing, coding, testing, and writing, the 3.0 release is now feature-complete, and so we are releasing the first beta so
It's finally here!
After many, many hours of designing, coding, testing, and writing, the 3.0 release is now feature-complete, and so we are releasing the first beta so that you can start testing all the new goodies with your apps. As before, this release includes native wheels with Cython support for Linux, macOS, and Windows.
👉 3.0.0b1 on PyPI 👉 ASGI Tutorial
Again, many thanks go out to the talented and well-dressed community members who have contributed to the Falcon 3.0.0 release. It has been a long road, and we have very much appreciated everyone's patience and input along the way. Adding features like native ASGI support, lean-and-mean WebSocket handling, and incredibly efficient and robust multipart form parsing, was no easy task. But we wanted to get it right and deliver a well-tested, forward-looking feature set sans hacks and compatibility layers.
Please see RTD for the complete changelog for the next major release of Falcon, and please try out the beta with some of your apps. Let us know in falconry/dev if you run into any issues.
We really need all hands on deck to ensure this is a rock-solid release.
Thank you!
This third alpha includes WebSocket support, improved documentation, and bug fixes. This is also the first time we are publishing native wheels with C
This third alpha includes WebSocket support, improved documentation, and bug fixes. This is also the first time we are publishing native wheels with Cython support for Linux, MacOS, and Windows. It is likely this will be the final pre-release before the first beta, at which time the ASGI interface design will be frozen.
Please see RTD for the latest documentation, and _newsfragments for the list of changes since 2.0.
Install from PyPi with pip install --pre -U falcon
Note: There's a bug that slipped through our tests re not lazy-importing msgpack for the WebSocket media handler. We'll get that fixed for the next pre-release. 🤦🏻♂️
Nothing published for this version
Nothing published for this version
Please carefully review the list of breaking changes below to see what you may need to tweak in your app to make it compatible with this release.
Many thanks to all of our awesome contributors (listed down below) who made this release possible!
In 2.0 we added a number of new convenience methods and properties. We also made it a lot cleaner and less error-prone to assign multiple routes to the same resource class via suffixed responders.
Also noteworthy is the significant effort we invested in improving the accuracy, clarity, and breadth of the docs. We hope these changes will help make the framework easier to learn for newcomers.
Middleware methods can now short-circuit request processing, and we improved cookie and ETag handling. Plus, the testing framework received several improvements to make it easier to simulate certain types of requests.
As this is the first major release that we have had in quite a while, we have taken the opportunity to clean up many parts of the framework. Deprecated variables, methods, and classes have been removed, along with all backwards-compatibility shims for old method signatures. We also changed the defaults for a number of request options based on community feedback.
Please carefully review the list of breaking changes below to see what you may need to tweak in your app to make it compatible with this release.
CPython 3.7 is now fully supported.
Falcon 2.x series is the last to support Python language version 2. As a result, support for CPython 2.7 and PyPy2.7 will be removed in Falcon 3.0.
Support for CPython 3.4 is now deprecated and will be removed in Falcon 3.0.
Support for CPython 2.6, CPython 3.3 and Jython 2.7 has been dropped.
Previously, several methods in the ~falcon.Response class could be used to attempt to set raw cookie headers. However, due to the Set-Cookie header values not being combinable as a comma-delimited list, this resulted in an incorrect response being constructed for the user agent in the case that more than one cookie was being set. Therefore, the following methods of falcon.Response now raise an instance of ValueError if an attempt is made to use them for Set-Cookie: ~falcon.Response.set_header, ~falcon.Response.delete_header, ~falcon.Response.get_header, ~falcon.Response.set_headers.
falcon.testing.Result.json now returns None when the response body is empty, rather than raising an error.
~falcon.Request.get_param_as_bool now defaults to treating valueless parameters as truthy, rather than falsy. None is still returned by default when the parameter is altogether missing.
~falcon.Request.get_param_as_bool no longer raises an error for a valueless parameter when the blank_as_true keyword argument is False. Instead, False is simply returned in that case.
~falcon.RequestOptions.keep_blank_qs_values now defaults to True instead of False.
~falcon.RequestOptions.auto_parse_qs_csv now defaults to False instead of True.
independent_middleware kwarg on falcon.API now defaults to True instead of False.
The stream_len property of the ~falcon.Response class was changed to be an alias of the new ~falcon.Response.content_length property. Please use ~falcon.Response.set_stream or ~falcon.Response.content_length instead, going forward, as stream_len is now deprecated.
Request ~falcon.Request.context_type was changed from dict to a bare class implementing the mapping interface. (See also: bare_class_context_type)
Response ~falcon.Response.context_type was changed from dict to a bare class implementing the mapping interface. (See also: bare_class_context_type)
~.media.JSONHandler and ~.HTTPError no longer use ujson in lieu of the standard json library (when ujson is available in the environment). Instead, ~.media.JSONHandler can now be configured to use arbitrary dumps() and loads() functions. If you also need to customize ~.HTTPError serialization, you can do so via ~.API.set_error_serializer.
The find() method for a custom router is now required to accept the req keyword argument that was added in a previous release. The backwards-compatible shim was removed.
All middleware methods and hooks must now accept the arguments as specified in the relevant interface definitions as of Falcon 2.0. All backwards-compatible shims have been removed.
Custom error serializers are now required to accept the arguments as specified by ~.API.set_error_serializer for the past few releases. The backwards-compatible shim has been removed.
An internal function, make_router_search(), was removed from the api_helpers module.
An internal function, wrap_old_error_serializer(), was removed from the api_helpers module.
In order to improve performance, the falcon.Request.headers and falcon.Request.cookies properties now return a direct reference to an internal cached object, rather than making a copy each time. This should normally not cause any problems with existing apps since these objects are generally treated as read-only by the caller.
The falcon.Request.stream attribute is no longer wrapped in a bounded stream when Falcon detects that it is running on the wsgiref server. If you need to normalize stream semantics between wsgiref and a production WSGI server, ~falcon.Request.bounded_stream may be used instead.
falcon.Request.cookies now gives precedence to the first value encountered in the Cookie header for a given cookie name, rather than the last.
The ordering of the parameters passed to custom error handlers was adjusted to be more intuitive and consistent with the rest of the framework:
# Before def handle_error(ex, req, resp, params): pass # Falcon 2.0 def handle_error(req, resp, ex, params): pass
See also: ~.API.add_error_handler
~.falcon.RequestOptions.strip_url_path_trailing_slash now defaults to False instead of True.
The deprecated falcon.testing.TestCase.api property was removed.
The deprecated falcon.testing.TestCase.api_class class variable was removed.
The deprecated falcon.testing.TestBase class was removed.
The deprecated falcon.testing.TestResource class was removed.
The deprecated protocol property was removed from the ~falcon.Request class.
The deprecated get_param_as_dict() method alias was removed from the ~falcon.Request class. Please use ~falcon.Request.get_param_as_json instead.
Routers were previously allowed to accept additional args and keyword arguments, and were not required to use the variadic form. Now, they are only allowed to accept additional options as variadic keyword arguments, and to ignore any arguments they don't support. This helps overridden router logic be less fragile in terms of their interface contracts, which also makes it easier to keep Falcon backwards-compatible in the face of any future changes in this area.
~.API.add_route previously accepted *args, but now no longer does.
The add_route() method for custom routers no longer takes a method_map argument. Custom routers should, instead, call the ~falcon.routing.map_http_methods function directly from their add_route() method if they require this mapping.
The serialize() media handler method now receives an extra content_type argument, while the deserialize() method now takes stream, content_type, and content_length arguments, rather than a single raw argument. The raw data can still be obtained by executing raw = stream.read().
See also: ~.media.BaseHandler
The deprecated falcon.routing.create_http_method_map() method was removed.
The keyword arguments for ~falcon.uri.parse_query_string were renamed to be more concise:
# Before
parsed_values = parse_query_string(
query_string, keep_blank_qs_values=True, parse_qs_csv=False
)
# Falcon 2.0
parsed_values = parse_query_string(
query_string, keep_blank=True, csv=False
)
~.falcon.RequestOptions.auto_parse_qs_csv now defaults to False instead of True.
The HTTPRequestEntityTooLarge class was renamed to ~falcon.HTTPPayloadTooLarge.
Two of the keyword arguments for ~falcon.Request.get_param_as_int were renamed to avoid shadowing built-in Python names:
# Before
dpr = req.get_param_as_int('dpr', min=0, max=3)
# Falcon 2.0
dpr = req.get_param_as_int('dpr', min_value=0, max_value=3)
The falcon.media.validators.jsonschema.validate decorator now uses functools.wraps to make the decorated method look like the original.
Previously, ~.HTTPError instances for which the has_representation property evaluated to False were not passed to custom error serializers (such as in the case of types that subclass ~.NoRepresentation). This has now been fixed so that custom error serializers will be called for all instances of ~.HTTPError.
Request cookie parsing no longer uses the standard library for most of the parsing logic. This may lead to subtly different results for archaic cookie header formats, since the new implementation is based on RFC 6265.
The ~falcon.Request.if_match and ~falcon.Request.if_none_match properties now return a list of falcon.ETag objects rather than the raw value of the If-Match or If-None-Match headers, respectively.
When setting the ~falcon.Response.etag header property, the value will now be wrapped with double-quotes (if not already present) to ensure compliance with RFC 7232.
The default error serializer no longer sets the charset parameter for the media type returned in the Content-Type header, since UTF-8 is the default encoding for both JSON and XML media types. This should not break well-behaved clients, but could impact test cases in apps that assert on the exact value of the Content-Type header.
Similar to the change made to the default error serializer, the default JSON media type generally used for successful responses was also modified to no longer specify the charset parameter. This change affects both the falcon.DEFAULT_MEDIA_TYPE and falcon.MEDIA_JSON constants, as well as the default value of the media_type keyword argument specified for the falcon.API initializer. This change also affects the default value of the .RequestOptions.default_media_type and .ResponseOptions.default_media_type options.
Several performance optimizations were made to hot code paths in the framework to make Falcon 2.0 even faster than 1.4 in some cases.
Numerous changes were made to the docs to improve clarity and to provide better recommendations on how to best use various parts of the framework.
Added a new ~falcon.Response.headers property to the ~falcon.Response class.
Removed the six and python-mimeparse dependencies.
Added a new ~falcon.Response.complete property to the ~falcon.Response class. This can be used to short-circuit request processing when the response has been pre-constructed.
Request ~falcon.Request.context_type now defaults to a bare class allowing to set attributes on the request context object:
# Before req.context['role'] = 'trial' req.context['user'] = 'guest' # Falcon 2.0 req.context.role = 'trial' req.context.user = 'guest'
To ease the migration path, the previous behavior is supported by implementing the mapping interface in a way that object attributes and mapping items are linked, and setting one sets the other as well. However, as of Falcon 2.0, the dict context interface is considered deprecated, and may be removed in a future release.
Applications can work around this change by explicitly overriding ~falcon.Request.context_type to dict. (See also: bare_class_context_type)
Response ~falcon.Response.context_type now defaults to a bare class allowing to set attributes on the response context object:
# Before resp.context['cache_strategy'] = 'lru' # Falcon 2.0 resp.context.cache_strategy = 'lru'
To ease the migration path, the previous behavior is supported by implementing the mapping interface in a way that object attributes and mapping items are linked, and setting one sets the other as well. However, as of Falcon 2.0, the dict context interface is considered deprecated, and may be removed in a future release.
Applications can work around this change by explicitly overriding ~falcon.Response.context_type to dict. (See also: bare_class_context_type)
~.media.JSONHandler can now be configured to use arbitrary dumps() and loads() functions. This enables support not only for using any of a number of third-party JSON libraries, but also for customizing the keyword arguments used when (de)serializing objects.
Added a new method, ~falcon.Request.get_cookie_values, to the ~falcon.Request class. The new method supports getting all values provided for a given cookie, and is now the preferred mechanism for reading request cookies.
Optimized request cookie parsing. It is now roughly an order of magnitude faster.
~falcon.Response.append_header now supports appending raw Set-Cookie header values.
Multiple routes can now be added for the same resource instance using a suffix to distinguish the set of responders that should be used. In this way, multiple closely-related routes can be mapped to the same resource while preserving readability and consistency.
See also: ~.API.add_route
The falcon.media.validators.jsonschema.validate decorator now supports both request and response validation.
A static route can now be configured to return the data from a default file when the requested file path is not found.
See also: ~.API.add_static_route
The ordering of the parameters passed to custom error handlers was adjusted to be more intuitive and consistent with the rest of the framework:
# Before def handle_error(ex, req, resp, params): pass # Falcon 2.0 def handle_error(req, resp, ex, params): pass
See also: ~.API.add_error_handler.
All error classes now accept a headers keyword argument for customizing response headers.
A new method, ~falcon.Request.get_param_as_float, was added to the ~falcon.Request class.
A new method, ~falcon.Request.has_param, was added to the ~falcon.Request class.
A new property, ~falcon.Response.content_length, was added to the ~falcon.Response class. Either ~falcon.Response.set_stream or ~falcon.Response.content_length should be used going forward, as stream_len is now deprecated.
All get_param_*() methods of the ~falcon.Request class now accept a default argument.
A new header property, ~falcon.Response.expires, was added to the ~falcon.Response class.
The ~.routing.CompiledRouter class now exposes a ~falcon.routing.CompiledRouter.map_http_methods method that child classes can override in order to customize the mapping of HTTP methods to resource class methods.
The serialize() media handler method now receives an extra content_type argument, while the deserialize() method now takes stream, content_type, and content_length arguments, rather than a single raw argument. The raw data can still be obtained by executing raw = stream.read().
See also: ~.media.BaseHandler
The ~falcon.Response.get_header method now accepts a default keyword argument.
The ~falcon.testing.TestClient.simulate_request method now supports overriding the host and remote IP address in the WSGI environment, as well as setting arbitrary additional CGI variables in the WSGI environment.
The ~falcon.testing.TestClient.simulate_request method now supports passing a query string as part of the path, as an alternative to using the params or query_string keyword arguments.
Added a deployment guide to the docs for uWSGI and NGINX on Linux.
The ~.uri.decode method now accepts an unquote_plus keyword argument. The new argument defaults to False to avoid a breaking change.
The ~falcon.Request.if_match and ~falcon.Request.if_none_match properties now return a list of falcon.ETag objects rather than the raw value of the If-Match or If-None-Match headers, respectively.
~.API.add_error_handler now supports specifying an iterable of exception types to match.
The default error serializer no longer sets the charset parameter for the media type returned in the Content-Type header, since UTF-8 is the default encoding for both JSON and XML media types.
Similar to the change made to the default error serializer, the default JSON media type generally used for successful responses was also modified to no longer specify the charset parameter. This change affects both the falcon.DEFAULT_MEDIA_TYPE and falcon.MEDIA_JSON constants, as well as the default value of the media_type keyword argument specified for the falcon.API initializer. This change also affects the default value of the .RequestOptions.default_media_type and .ResponseOptions.default_media_type options.
Fixed a docs issue where with smaller browser viewports, the API documentation will start horizontal scrolling.
The color scheme for the docs was modified to fix issues with contrast and readability when printing the docs or generating PDFs.
The ~falcon.testing.TestClient.simulate_request method now forces header values to str on Python 2 as required by PEP-3333.
The HTTPRequestEntityTooLarge class was renamed to ~falcon.HTTPPayloadTooLarge and the reason phrase was updated per RFC 7231.
The falcon.CaseInsensitiveDict class now inherits from collections.abc.MutableMapping under Python 3, instead of collections.MutableMapping.
The \ufffd character is now disallowed in requested static file paths.
The falcon.media.validators.jsonschema.validate decorator now uses functools.wraps to make the decorated method look like the original.
The falcon-print-routes CLI tool no longer raises an unhandled error when Falcon is cythonized.
The plus character ('+') is no longer unquoted in the request path, but only in the query string.
Previously, ~.HTTPError instances for which the has_representation property evaluated to False were not passed to custom error serializers (such as in the case of types that subclass ~.NoRepresentation). This has now been fixed so that custom error serializers will be called for all instances of ~.HTTPError.
When setting the ~falcon.Response.etag header property, the value will now be wrapped with double-quotes (if not already present) to ensure compliance with RFC 7232.
Fixed TypeError being raised when using Falcon's testing framework to simulate a request to a generator-based WSGI app.
Many thanks to all of our talented and stylish contributors for this release!
Bertrand Lemasle
Patrick Schneeweis
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Reverted the breaking change in 1.4.0 to falcon.testing.Result.json. Minor releases should have no breaking changes.
(None)
(None)
(None)
Reverted the breaking change in 1.4.0 to falcon.testing.Result.json. Minor releases should have no breaking changes.
The README was not rendering properly on PyPI. This was fixed and a validation step was added to the build process.
Support for CPython 3.3 is now deprecated and will be removed in Falcon 2.0.
falcon.testing.Result.json now returns None when the response body is empty, rather than raising an error.
Python 3 is now supported on PyPy as of PyPy3.5 v5.10.
Support for CPython 3.3 is now deprecated and will be removed in Falcon 2.0.
As with the previous release, Python 2.6 and Jython 2.7 remain deprecated and will no longer be supported in Falcon 2.0.
We added a new method, ~.API.add_static_route, that makes it easy to serve files from a local directory. This feature provides an alternative to serving files from the web server when you don't have that option, when authorization is required, or for testing purposes.
Arguments can now be passed to hooks (see Hooks).
The default JSON media type handler will now use ujson, if available, to speed up JSON (de)serialization under CPython.
Semantic validation via the format keyword is now enabled for the ~falcon.media.validators.jsonschema.validate JSON Schema decorator.
We added a new helper, ~falcon.Request.get_param_as_uuid, to the ~falcon.Request class.
Falcon now supports WebDAV methods (RFC 3253), such as UPDATE and REPORT.
We added a new property, ~falcon.Response.downloadable_as, to the ~falcon.Response class for setting the Content-Disposition header.
~falcon.routing.create_http_method_map has been refactored into two new methods, ~falcon.routing.map_http_methods and ~falcon.routing.set_default_responders, so that custom routers can better pick and choose the functionality they need. The original method is still available for backwards-compatibility, but will be removed in a future release.
We added a new json param to ~falcon.testing.simulate_request et al. to automatically serialize the request body from a JSON serializable object or type (for a complete list of serializable types, see json.JSONEncoder).
~.TestClient's simulate_*() methods now call ~.TestClient.simulate_request to make it easier for subclasses to override ~.TestClient's behavior.
~.TestClient can now be configured with a default set of headers to send with every request.
The FAQ has been reorganized and greatly expanded.
We restyled the docs to match https://falconframework.org
Forwarded headers containing quoted strings with commas were not being parsed correctly. This has been fixed, and the parser generally made more robust.
~falcon.media.JSONHandler was raising an error under Python 2.x when serializing strings containing Unicode code points. This issue has been fixed.
Overriding a resource class and calling its responders via super() did not work when passing URI template params as positional arguments. This has now been fixed.
Python 3.6 was generating warnings for strings containing '\s' within Falcon. These strings have been converted to raw strings to mitigate the warning.
Several syntax errors were found and fixed in the code examples used in the docs.
Many thanks to all of our talented and stylish contributors for this release!
GriffGeorge
hynek
kgriffs
rhemz
santeyio
timc13
tyronegroves
vytas7
zhanghanyun
Your coding agent can read these notes before it upgrades. Set up the MCP server →