NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1757 most downloaded on PyPI
Brings async, event-driven capabilities to Django.
Last release 10 months ago
20 Nov 2025
Release timing varies
gaps range from 1 weeks to 1.5 years
Nearly every release is documented
notes for 58 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
11 years old
73 releases · first in 2015
Confirmed support for Django 6.0.
Confirmed support for Django 6.0.
Confirmed support for Python 3.14.
Added types extra for types-channels stubs. See installation docs.
Channels 4.3.1 is a bugfix release in the 4.3 series.
Confirmed support for Django 6.0.
Confirmed support for Python 3.14.
Added types extra for types-channels stubs. See installation docs.
Fixed testing live server setup when test DB name was not set.
One column per quarter.
Channels 4.3.1 is a bugfix release in the 4.3 series.
Fixed testing live server setup when test DB name was not set.
Updated asgiref dependency to v3.9+.
Updated asgiref dependency to v3.9+.
Dropped support for EOL Python and Django versions. Python 3.9 is now the minimum supported version.
Fixed compatibility of ChannelsLiveServerTestCase with Django 5.2.
Fixed DB setup for spawned testing subprocess, typically on Windows and macOS.
See the Version 4.3.0 release notes <https://channels.readthedocs.io/en/latest/releases/4.3.0.html>_ for more
details.
Channels 4.3 is a maintenance release in the 4.x series.
Updated asgiref dependency to v3.9+.
The ApplicationCommunicator testing utility will now return its result if the application is finished when sending input. Assert the CancelledError` rather than allowing a timeout in your tests if you're affected by this change.
Dropped support for EOL Python and Django versions. Python 3.9 is now the minimum supported version.
Fixed compatibility of ChannelsLiveServerTestCase with Django 5.2.
Fixed DB setup for spawned testing subprocess, typically on Windows and macOS.
These were renamed in 4.2.1 but (as internal methods) without deprecation. They are restored (and deprecated) here to allow updating channel layers us…
Added fallbacks for old valid channel/group name checks.
These were renamed in 4.2.1 but (as internal methods) without deprecation. They are restored (and deprecated) here to allow updating channel layers using them.
Channels 4.2.2 is a bugfix release in the 4.2 series.
Added fallbacks for old valid channel/group name checks.
These (internal) methods were renamed in v4.2.1 without deprecation. This release adds (deprecated) fallback aliases to allow time for channel layers to update.
Channels 4.2.1 primarily updates the metadata for supported Python and Django versions.
Channels 4.2.1 primarily updates the metadata for supported Python and Django versions.
Added official support for Django 5.2 LTS.
Added official support for Python 3.13.
Added a warning for the length of the channel layer group names.
See also the Version 4.2.1 release notes <https://channels.readthedocs.io/en/latest/releases/4.2.1.html>_ in the docs.
Channels 4.2.1 is a bugfix release in the 4.2 series.
Added official support for Django 5.2 LTS.
Added official support for Python 3.13.
Added a warning for the length of the channel layer group names.
Channels 4.2 introduces a couple of major but backwards-compatible changes, including most notably enhanced async suppport and fixing a long-standing
Channels 4.2 introduces a couple of major but backwards-compatible changes, including most notably enhanced async suppport and fixing a long-standing bug where tests would try and close db connections and erroneously fail.
There are a number of other small bugfixes. Please ensure to review the
Version 4.2.0 release notes <https://channels.readthedocs.io/en/latest/releases/4.2.0.html>_ for full
details.
Channels 4.2 introduces a couple of major but backwards-compatible changes, including most notably enhanced async support and fixing a long-standing bug where tests would try and close db connections and erroneously fail.
Additionally, support has been added for Django 5.1.
Support for asynchronous consumers has been greatly improved. The documentation has been updated to reflect the async ORM features added in Django 4.2. A new channels.db.aclose_old_connections function has been added to easily close old database connections in async consumers.
Warning: Channels now automatically closes connections in async consumers before a new connection, after receiving message (but before dispatching to consumer code), and after disconnecting.
This change has been made to more closely align with Django's request/response cycle, and to help users avoid attempting to use stale/broken connections.
Notably, Channels does NOT close connections before or after a consumer sends data. This is to avoid database churn and more closely align with user expectations. Instead, users are expected to call aclose_old_connections occasionally during long-lived async connections.
Additionally, channels will automatically use the new async interface for sessions if Django 5.1 or greater is installed. This new interface can be slightly faster in certain cases as it does not always need to context-switch into synchronous execution. This does require a backwards-incompatible change to channels.sessions.InstanceSessionWrapper: the save_session function is now async. If InstanceSessionWrapper was being subclassed in some way (note that this class is an implementation detail and not documented) and save_session was being called or overridden, it will need to be updated to be called with await or defined as async, respectively.
InMemoryChannelLayer has been greatly improved: it now honors expiry times and per-channel capacities, has parallel sending and a safer internal implementation. Note: queue capacities can no longer be changed after a channel has been created.
Thanks to @devkral (Alexander)
Database connections are no longer closed inside tests, which prevents erroneous "Cannot operate on a closed database" errors when running tets.
Thanks to Jon Janzen.
An old import override and an unused deprecation message were removed
Thanks to @sevdog (Devid) and Jon Janzen.
WebsocketCommunicator now has informative assert error messages
Thanks to Karel Hovorka.
WebsocketConsumer now checks that "text" is not None before attempting to use it. This improves support for Hypercorn.
Thanks to Joaquín Ossandon.
BaseChannelLayer now has prototypes on all its methods to improve the hit-rate for smart autocompleters when users need to author their own channel layer and need to implement all required methods.
Thanks to Jophy Ye.
Channels 4.1 is maintenance release in the 4.x series.
Channels 4.1 is maintenance release in the 4.x series.
The main change is an update in the required Python and Django version. Python 3.8, and Django 4.2 are now the minimum required versions.
There are a number of other small bugfixes. Please ensure to review the
Version 4.1.0 release notes <https://channels.readthedocs.io/en/latest/releases/4.1.0.html>_ for full
details.
Channels 4.1 is maintenance release in the 4.x series.
A Python version of 3.8 or higher is required.
Django 4.2 is now the minimum supported version.
Exceptions in HttpConsumer are now correctly propagated.
Thanks to Adam Johnson.
URLRouter is updated for compatibility with in-development changes in Django.
Thanks to Adam Johnson.
URLRouter is updated to correctly handle root_path.
Thanks to Alejandro R. Sedeño.
Websocket consumers are updated for newer ASGI spec versions, adding the headers parameter for the accept event, and reason for the close event.
Thanks to Kristján Valur Jónsson.
Again, this is a major version change. Amongst other changes, large amounts of the Django-wrapping code deprecated in Channels v3 has now been removed…
Channels 4 is the next major version of the Channels package. Together with the matching Daphne v4 and channels-redis v4 releases, it updates dependencies, fixes issues, and removes outdated code. It so provides the foundation for Channels development going forward.
In most cases, you can update now by updating channels, daphne, and
channels-redis as appropriate, with pip, and by adding daphne at
the top of your INSTALLED_APPS setting.
First pip::
pip install -U 'channels[daphne]' channels-redis
Then in your Django settings file::
INSTALLED_APPS = [
"daphne",
...
]
Again, this is a major version change. Amongst other changes, large amounts of
the Django-wrapping code deprecated in Channels v3 has now been removed, in
favour of Django's own ASGI handling, and the runserver command has been
moved into the Daphne package.
Please ensure to review the Version 4.0.0 release notes <https://channels.readthedocs.io/en/latest/releases/4.0.0.html>_ for full
details.
Channels 4 is the next major version of the Channels package. Together with the matching Daphne v4 and channels-redis v4 releases, it updates dependencies, fixes issues, and removes outdated code. It so provides the foundation for Channels development going forward.
In most cases, you can update now by updating channels, daphne, and channels-redis as appropriate, with pip, and by adding daphne at the top of your INSTALLED_APPS setting.
First pip:
pip install -U 'channels[daphne]' channels-redis
Then in your Django settings file:
INSTALLED_APPS = [
"daphne",
...
]
Read on for the details.
In general Channels will try to follow Python and Django supported versions.
As of release, that means Python 3.7, 3.8, 3.9, and 3.10, as well as Django 3.2, 4.0, and 4.1 are currently supported.
As a note, we reserve the right to drop older Python versions, or the older Django LTS, once the newer one is released, before their official end-of-life if this is necessary to ease development.
Dropping older Python and Django versions will be done in minor version releases, and will not be considered to require a major version change.
The async support in both Python and Django continues to evolve rapidly. We advise you to always upgrade to the latest versions in order to avoid issues in older versions if you're building an async application.
Dropped support for Python 3.6.
Minimum Django version is now Django 3.2.
Added compatibility with Django 4.1.
In order to allow users of other ASGI servers to use Channels without the overhead of Daphne and Twisted, the Daphne application server is now an optional dependency, installable either directly or with the daphne extra, as per the pip example above.
Where Daphne is used daphne>=4.0.0 is required. The channels[daphne] extra assures this.
The runserver command is moved to the daphne package.
In order to use the runserver command, add daphne to your INSTALLED_APPS, before django.contrib.staticfiles:
INSTALLED_APPS = [
"daphne",
...
]
There is a new system check to ensure this ordering.
Note, the runworker command remains a part of the channels app.
Use of ChannelsLiveServerTestCase still requires Daphne.
In order to add initial ASGI support to Django, Channels originally provided tools for wrapping your Django application and serving it under ASGI. This included an ASGI handler class, an ASGI HTTP request object, and an ASGI compatible version of the staticfiles handler for use with runserver
Improved equivalents to all of these are what has been added to Django since Django version 3.0. As such serving of Django HTTP applications (whether using sync or async views) under ASGI is now Django's responsibility, and the matching Channels classes have been removed.
Use of these classes was deprecated in Channels v3 and, if you've already moved to the Django equivalents there is nothing further to do.
Removed deprecated static files handling in favor of django.contrib.staticfiles.
Removed the deprecated AsgiHandler, which wrapped Django views, in favour of Django's own ASGI support. You should use Django's get_asgi_application to provide the http handler for ProtocolTypeRouter, or an appropriate path for URLRouter, in order to route your Django application.
The supporting AsgiRequest is also removed, as it was only used for AsgiHandler.
Removed deprecated automatic routing of http protocol handler in ProtocolTypeRouter. You must explicitly register the http handler in your application if using ProtocolTypeRouter.
The minimal asgi.py file routing the Django ASGI application under a ProtocolTypeRouter will now look something like this:
import os
from channels.routing import ProtocolTypeRouter
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
})
i.e. We use Django's get_asgi_application(), and explicitly route an http handler for ProtocolTypeRouter. This is merely for illustration of the changes. Please see the docs for more complete examples.
The use of the guarantee_single_callable() compatibility shim is removed. All applications must be ASGI v3 single-callables.
Removed the consumer_started and consumer_finished signals, unused since the 2.0 rewrite.
Fixed ChannelsLiveServerTestCase when running on systems using the spawn multiprocessing start method, such as macOS and Windows.
Nothing published for this version
Channels 3.0.5 is a bugfix release in the 3.0 series.
Channels 3.0.5 is a bugfix release in the 3.0 series.
Please see the Version 3.0.5 release notes <https://channels.readthedocs.io/en/latest/releases/3.0.5.html>_ for full
details.
Channels 3.0.5 is a bugfix release in the 3.0 series.
Removed use of providing_args keyword argument to consumer started signal, as support for this was removed in Django 4.0.
Drops support for end-of-life Python 3.6 and Django 3.0 and 3.1.
Channels 3.0.4 is a bugfix release in the 3.0 series.
Channels 3.0.4 is a bugfix release in the 3.0 series.
Please see the Version 3.0.4 release notes <https://channels.readthedocs.io/en/latest/releases/3.0.4.html>_ for full
details.
Channels 3.0.4 is a bugfix release in the 3.0 series.
Usage of urlparse in OriginValidator is corrected to maintain compatibility with recent point-releases of Python.
The import of django.contrib.auth.models.AnonymousUser in channels.auth is deferred until runtime, in order to avoid errors if AuthMiddleware or AuthMiddlewareStack were imported before django.setup() was run.
CookieMiddleware adds support for the samesite flag.
WebsocketConsumer.init() and AsyncWebsocketConsumer.init() no longer make a bad super() call to object.init().
None.
This is a security release for CVE-2020-35681. Please see the Version 3.0.3 release notes _ for full details.
Fixed a bug in Channels 3.0 where the legacy channels.http.AsgiHandler
would not correctly isolate per-request scopes.
This is a security release for CVE-2020-35681. Please see the Version 3.0.3 release notes <https://channels.readthedocs.io/en/latest/releases/3.0.3.html>_ for full
details.
Channels 3.0.3 fixes a security issue in Channels 3.0.2
The legacy channels.http.AsgiHandler class, used for handling HTTP type requests in an ASGI environment prior to Django 3.0, did not correctly separate request scopes in Channels 3.0. In many cases this would result in a crash but, with correct timing responses could be sent to the wrong client, resulting in potential leakage of session identifiers and other sensitive data.
This issue affects Channels 3.0.x before 3.0.3, and is resolved in Channels 3.0.3.
Users of ProtocolTypeRouter not explicitly specifying the handler for the 'http' key, or those explicitly using channels.http.AsgiHandler, likely to support Django v2.2, are affected and should update immediately.
Note that both an unspecified handler for the 'http' key and using channels.http.AsgiHandler are deprecated, and will raise a warning, from Channels v3.0.0
This issue affects only the legacy channels provided class, and not Django's similar ASGIHandler, available from Django 3.0. It is recommended to update to Django 3.0+ and use the Django provided ASGIHandler.
A simplified asgi.py script will look like this:
import os
from django.core.asgi import get_asgi_application
# Fetch Django ASGI application early to ensure AppRegistry is populated
# before importing consumers and AuthMiddlewareStack that may import ORM
# models.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
django_asgi_app = get_asgi_application()
# Import other Channels classes and consumers here.
from channels.routing import ProtocolTypeRouter, URLRouter
application = ProtocolTypeRouter({
# Explicitly set 'http' key using Django's ASGI application.
"http": django_asgi_app,
),
})
Please see /deploying for a more complete example.
Fixes a bug in Channels 3.0 where StaticFilesWrapper was not updated to the ASGI 3 single-callable interface.
Fixes a bug in Channels 3.0 where StaticFilesWrapper was not updated to
the ASGI 3 single-callable interface.
Users of the runworker command should ensure to update asgiref to
version 3.3.1 or later.
Channels 3.0.2 fixes a bug in Channels 3.0.1
Fixes a bug in Channels 3.0 where StaticFilesWrapper was not updated to the ASGI 3 single-callable interface.
Users of the runworker command should ensure to update asgiref to version 3.3.1 or later, where an issue in asgiref.server.StatelessServer was addressed.
Fixes a bug in Channels 3.0 where SessionMiddleware would not correctly isolate per-instance scopes.
SessionMiddleware would not correctly
isolate per-instance scopes.Channels 3.0.1 fixes a bug in Channels 3.0.
Fixes a bug in Channels 3.0 where SessionMiddleware would not correctly isolate per-instance scopes.
Updated to ASGI v3, and added support for Django 3.0+.
Updated to ASGI v3, and added support for Django 3.0+.
This is a major version change requiring updates to consumers and middleware.
Please see the full Version 3.0.0 release notes <https://channels.readthedocs.io/en/latest/releases/3.0.0.html>_ for details.
The Channels 3 update brings Channels into line with Django's own async ASGI support, introduced with Django 3.0.
Channels now integrates with Django's async HTTP handling, whilst continuing to support WebSockets and other exciting consumer types.
Channels 3 supports Django 3.x and beyond, as well continuing to support the Django 2.2 LTS. We will support Django 2.2 at least until the Django 3.2 LTS is released, yet may drop support after that, but before Django 2.2 is officially end-of-life.
Likewise, we support Python 3.6+ but we strongly advise you to update to the latest Python versions, so 3.9 at the time of release.
In both our Django and Python support, we reflect the reality that async Python and async Django are still both evolving rapidly. Many issues we see simply disappear if you update. Whatever you are doing with async, you should make sure you're on the latest versions.
The highlight of this release is the upgrade to ASGI v3, which allows integration with Django's ASGI support. There are also two additional deprecations that you will need to deal with if you are updating an existing application.
Consumers are now ASGI 3 single-callables with the signature:
application(scope, receive, send)
For generic consumers this change should be largely transparent, but you will need to update __init__() (no longer taking the scope) and __call__() (now taking the scope) if you implemented these yourself.
Consumers now have an as_asgi() class method you need to call when setting up your routing:
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()),
]
This returns an ASGI application that will instantiate the consumer per-request. It's similar to Django's as_view(), which serves the same purpose. You can pass in keyword arguments for initialization if your consumer requires them.
Middleware will also need to be updated to the ASGI v3 signature. The channels.middleware.BaseMiddleware class is simplified, and available as an example. You probably don't need to actually subclass it under ASGI 3.
Using ProtocolTypeRouter without an explicit "http" key is now deprecated.
Following Django conventions, your entry point script should be named asgi.py, and you should use Django's get_asgi_application(), that is used by Django's default asgi.py template to route the "http" handler:
from django.core.asgi import get_asgi_application
application = ProtocolTypeRouter({
"http": get_asgi_application(),
# Other protocols here.
})
Once the deprecation is removed, when we drop support for Django 2.2, not specifying an "http" key will mean that your application will not handle HTTP requests.
The Channels built-in HTTP protocol AsgiHandler is also deprecated. You should update to Django 3.0 or higher and use Django's get_asgi_application(). Channel's AsgiHandler will be removed when we drop support for Django 2.2.
Wraps session save calls in database_sync_to_async(), for compatibility with Django 3.0's async_unsafe() checks.
Wraps session save calls in database_sync_to_async(), for compatibility
with Django 3.0's async_unsafe() checks.
Drops compatibility with all Django versions lower than 2.2.
Channels 2.4 brings compatibility with Django 3.0s async_unsafe() checks. (Specifically we ensure session save calls are made inside an asgiref database_sync_to_async().)
If you are using Daphne, it is recommended that you install Daphne version 2.4.1 or later for full compatibility with Django 3.0.
In line with the guidance provided by Django's supported versions policy we now also drop support for all Django versions before 2.2, which is the current LTS.
Adds compatibility with Python 3.8.
Adjusted AsgiHandler HTTP body handling to use a spooled temporary file, rather than reading the whole request body into memory.
Adjusted AsgiHandler HTTP body handling to use a spooled temporary file,
rather than reading the whole request body into memory.
As a result, AsgiRequest.__init__() is adjusted to expect a file-like
stream, rather than the whole body as bytes. Test cases instantiating
requests directly will likely need to be updated to wrap the provided body
in, e.g., io.BytesIO.
Channels 2.3.0 updates the AsgiHandler HTTP request body handling to use a spooled temporary file, rather than reading the whole request body into memory.
This significantly reduces the maximum memory requirements when serving Django views, and protects from DoS attacks, whilst still allowing large file uploads — a combination that had previously been difficult.
Many thanks to Ivan Ergunov for his work on the improvements! 🎩
As a result of the reworked body handling, AsgiRequest.__init__() is adjusted to expect a file-like stream, rather than the whole body as bytes.
Test cases instantiating requests directly will likely need to be updated to wrap the provided body in, e.g., io.BytesIO.
We're looking to address a few issues around AsyncHttpConsumer. Any human-power available to help on that, truly appreciated. 🙂
Updated requirements for ASGI v3 and Daphne 2.3.
Channels 2.2.0 updates the requirements for ASGI version 3, and the supporting Daphne v2.3 release.
None.
HTTP request body size limit is now enforced
HTTP request body size limit is now enforced
database_sync_to_async now closes old connections before it runs code
Auth middleware closes old connections before it runs
Channels 2.1.7 is another bugfix release in the 2.1 series, and the last release (at least for a long while) with Andrew Godwin as the primary maintainer.
Thanks to everyone who has used, supported, and contributed to Channels over the years, and I hope we can keep it going with community support for a good while longer.
HTTP request body size limit is now enforced (the one set by the DATA_UPLOAD_MAX_MEMORY_SIZE setting)
database_sync_to_async now closes old connections before it runs code, which should prevent some connection errors in long-running pages or tests.
The auth middleware closes old connections before it runs, to solve similar old-connection issues.
None.
HttpCommunicator now extracts query strings correctly
HttpCommunicator now extracts query strings correctly
AsyncHttpConsumer provides channel layer attributes
Prevent late-Daphne import errors
Channels 2.1.6 is another bugfix release in the 2.1 series.
HttpCommunicator now extracts query strings correctly from its provided arguments
AsyncHttpConsumer provides channel layer attributes following the same conventions as other consumer classes
Prevent late-Daphne import errors where importing daphne.server didn't work due to a bad linter fix.
None.
Django middleware caching now works on Django 1.11 and Django 2.0. The previous release only ran on 2.1.
Channels 2.1.5 is another bugfix release in the 2.1 series.
Django middleware caching now works on Django 1.11 and Django 2.0. The previous release only ran on 2.1.
None.
Django middleware is now cached rather than instantiated per request resulting in a significant speed improvement
Django middleware is now cached rather than instantiated per request resulting in a significant speed improvement
ChannelServerLiveTestCase now serves static files again
Improved error message resulting from bad Origin headers
runserver logging now goes through the Django logging framework
Generic consumers can now have non-default channel layers
Improved error when accessing scope['user'] before it's ready
Channels 2.1.4 is another bugfix release in the 2.1 series.
Django middleware is now cached rather than instantiated per request resulting in a significant speed improvement. Some middleware took seconds to load and as a result Channels was unusable for HTTP serving before.
ChannelServerLiveTestCase now serves static files again.
Improved error message resulting from bad Origin headers.
runserver logging now goes through the Django logging framework to match modern Django.
Generic consumers can now have non-default channel layers - set the channel_layer_alias property on the consumer class
Improved error when accessing scope['user'] before it's ready - the user is not accessible in the constructor of ASGI apps as it needs an async environment to load in. Previously it raised a generic error when you tried to access it early; now it tells you more clearly what's happening.
None.
An ALLOWED_ORIGINS value of "*" will now also allow requests without a Host header at all (especially important for tests)
An ALLOWED_ORIGINS value of "*" will now also allow requests without a Host header at all (especially important for tests)
The request.path value is now correct in cases when a server has SCRIPT_NAME set
Errors that happen inside channel listeners inside a runworker or Worker class are now raised rather than suppressed
Channels 2.1.3 is another bugfix release in the 2.1 series.
An ALLOWED_ORIGINS value of "*" will now also allow requests without a Host header at all (especially important for tests)
The request.path value is now correct in cases when a server has SCRIPT_NAME set.
Errors that happen inside channel listeners inside a runworker or Worker class are now raised rather than suppressed.
None.
AsyncHttpConsumer now has a disconnect() method you can override
AsyncHttpConsumer now has a disconnect() method you can override
Session and authentication middleware is now non-blocking.
URL routing context now includes default arguments from the URLconf.
The FORCE_SCRIPT_NAME setting is now respected in ASGI mode.
ALLOWED_HOSTS is now set correctly during LiveServerTests.
Channels 2.1.2 is another bugfix release in the 2.1 series.
Special thanks to people at the DjangoCon Europe sprints who helped out with several of these fixes.
Session and authentication middleware has been overhauled to be non-blocking. Previously, these middlewares potentially did database or session store access in the synchronous ASGI constructor, meaning they would block the entire event loop while doing so.
Instead, they have now been modified to add LazyObjects into the scope in the places where the session or user will be, and then when the processing goes through their asynchronous portion, those stores are accessed in a non-blocking fashion.
This should be an un-noticeable change for end users, but if you see weird behaviour or an unresolved LazyObject, let us know.
AsyncHttpConsumer now has a disconnect() method you can override if you want to perform actions (such as leaving groups) when a long-running HTTP request disconnects.
URL routing context now includes default arguments from the URLconf in the context's url_route key, alongside captured arguments/groups from the URL pattern.
The FORCE_SCRIPT_NAME setting is now respected in ASGI mode, and lets you override where Django thinks the root URL of your application is mounted.
ALLOWED_HOSTS is now set correctly during LiveServerTests, meaning you will no longer get 400 Bad Request errors during these test runs.
None.
The scope["user"] object is no longer a lazy object, as this conflicts with any async-based consumers.
Channels 2.1.1 is a bugfix release for an important bug in the new async authentication code.
None.
Previously, the object in scope["user"] was one of Django's SimpleLazyObjects, which then called our get_user async function via async_to_sync.
This worked fine when called from SyncConsumers, but because async environments do not run attribute access in an async fashion, when the body of an async consumer tried to call it, the asgiref library flagged an error where the code was trying to call a synchronous function during a async context.
To fix this, the User object is now loaded non-lazily on application startup. This introduces a blocking call during the synchronous application constructor, so the ASGI spec has been updated to recommend that constructors for ASGI apps are called in a threadpool and Daphne 2.1.1 implements this and is recommended for use with this release.
None.
Async HTTP Consumers and WebSocket Consumers both gained new functionality (groups, subprotocols, and an async HTTP variant)
Async HTTP Consumers and WebSocket Consumers both gained new functionality (groups, subprotocols, and an async HTTP variant)
URLRouters now allow nesting
Async login and logout functions for sessions
Expiry and groups in the in-memory channel layer
Improved Live Server test case
More powerful OriginValidator
Other small changes and fixes in the full release notes.
Channels 2.1 brings a few new major changes to Channels as well as some more minor fixes. In addition, if you've not yet seen it, we now have a long-form tutorial to better introduce some of the concepts and sync versus async styles of coding.
There is a new native-async HTTP consumer class, channels.generic.http.AsyncHttpConsumer. This allows much easier writing of long-poll endpoints or other long-lived HTTP connection handling that benefits from native async support.
You can read more about it in the /topics/consumers documentation.
These consumer classes now all have built-in group join and leave functionality, which will make a consumer join all group names that are in the iterable groups on the consumer class (this can be a static list or a @property method).
In addition, the accept methods on both variants now take an optional subprotocol argument, which will be sent back to the WebSocket client as the subprotocol the server has selected. The client's advertised subprotocols can, as always, be found in the scope as scope["subprotocols"].
URLRouter instances can now be nested inside each other and, like Django's URL handling and include, will strip off the matched part of the URL in the outer router and leave only the unmatched portion for the inner router, allowing reusable routing files.
Note that you cannot use the Django include function inside of the URLRouter as it assumes a bit too much about what it is given as its left-hand side and will terminate your regular expression/URL pattern wrongly.
As well as overhauling the internals of the AuthMiddleware, there are now also login and logout async functions you can call in consumers to log users in and out of the current session.
Due to the way cookies are sent back to clients, these come with some caveats; read more about them and how to use them properly in /topics/authentication.
The in-memory channel layer has been extended to have full expiry and group support so it should now be suitable for drop-in replacement for most test scenarios.
The ChannelsLiveServerTestCase has been rewritten to use a new method for launching Daphne that should be more resilient (and faster), and now shares code with the Daphne test suite itself.
Ports are now left up to the operating system to decide rather than being picked from within a set range. It also now supports static files when the Django staticfiles app is enabled.
In addition, the Communicator classes have gained a receive_nothing method that allows you to assert that the application didn't send anything, rather than writing this yourself using exception handling. See more in the /topics/testing documentation.
As well as removing the print statements that accidentally got into the last release, this has been overhauled to more correctly match against headers according to the Origin header spec and align with Django's ALLOWED_HOSTS setting.
It can now also enforce protocol (http versus https) and port, both optionally.
print statements that accidentally got left in the Origin validation code were removed.
The runserver command now shows the version of Channels you are running.
Orphaned tasks that may have caused warnings during test runs or occasionally live site traffic are now correctly killed off rather than letting them die later on and print warning messages.
WebsocketCommunicator now accepts a query string passed into the constructor and adds it to the scope rather than just ignoring it.
Test handlers will correctly handle changing the CHANNEL_LAYERS setting via decorators and wipe the internal channel layer cache.
SessionMiddleware can be safely nested inside itself rather than causing a runtime error.
The format taken by the OriginValidator for its domains has changed and *.example.com is no longer allowed; instead, use .example.com to match a domain and all its subdomains.
If you previously nested URLRouter instances inside each other both would have been matching on the full URL before, whereas now they will match on the unmatched portion of the URL, meaning your URL routes would break if you had intended this usage.
SyncConsumer now terminates old database connections, and there is a new database_sync_to_async wrapper to allow async connections to do the same.
Channels 2.0.2 is a patch release of Channels, fixing a bug in the database connection handling.
As always, when updating Channels make sure to also update its dependencies (asgiref and daphne) as these also get their own bugfix updates, and some bugs that may appear to be part of Channels are actually in those packages.
There is a new channels.db.database_sync_to_async wrapper that is like sync_to_async but also closes database connections for you. You can read more about usage in /topics/databases.
SyncConsumer and all its descendant classes now close database connections when they exit.
None.
AsyncWebsocketConsumer and AsyncJsonWebsocketConsumer classes added
AsyncWebsocketConsumer and AsyncJsonWebsocketConsumer classes added
OriginValidator and AllowedHostsOriginValidator ASGI middleware is now available
URLRouter now correctly resolves long lists of URLs
Channels 2.0.1 is a patch release of channels, adding a couple of small new features and fixing one bug in URL resolution.
As always, when updating Channels make sure to also update its dependencies (asgiref and daphne) as these also get their own bugfix updates, and some bugs that may appear to be part of Channels are actually in those packages.
There are new async versions of the Websocket generic consumers, AsyncWebsocketConsumer and AsyncJsonWebsocketConsumer. Read more about them in /topics/consumers.
The old allowed_hosts_only decorator has been removed (it was accidentally included in the 2.0 release but didn't work) and replaced with a new OriginValidator and AllowedHostsOriginValidator set of ASGI middleware. Read more in /topics/security.
A bug in URLRouter which didn't allow you to match beyond the first URL in some situations has been resolved, and a test suite was added for URL resolution to prevent it happening again.
None.
Major backwards-incompatible rewrite to move to an asyncio base and remove the requirement to transport data over the network, as well as overhauled g
Channels 2.0 is a major rewrite of Channels, introducing a large amount of changes to the fundamental design and architecture of Channels. Notably:
Data is no longer transported over a channel layer between protocol server and application; instead, applications run inside their protocol servers (like with WSGI).
To achieve this, the entire core of channels is now built around Python's asyncio framework and runs async-native down until it hits either a Django view or a synchronous consumer.
Python 2.7 and 3.4 are no longer supported.
More detailed information on the changes and tips on how to port your applications can be found in our /one-to-two documentation in the 2.x docs version.
Channels 2 is regrettably not backwards-compatible at all with Channels 1 applications due to the large amount of re-architecting done to the code and the switch from synchronous to asynchronous runtimes.
A migration guide is available in the 2.x docs version, and a lot of the basic concepts are the same, but the basic class structure and imports have changed.
Our apologies for having to make a breaking change like this, but it was the only way to fix some of the fundamental design issues in Channels 1. Channels 1 will continue to receive security and data-loss fixes for the foreseeable future, but no new features will be added.
Nothing published for this version
Nothing published for this version
The runserver server_cls override no longer fails with more modern Django versions that pass an ipv6 parameter.
runserver server_cls override no longer fails with more modern
Django versions that pass an ipv6 parameter.Channels 1.1.5 is a packaging release for the 1.1 series, released on June 28th, 2017.
None.
The runserver server_cls override no longer fails with more modern Django versions that pass an ipv6 parameter.
None.
The Daphne dependency requirement was bumped to 1.3.0.
Channels 1.1.5 is a packaging release for the 1.1 series, released on June 16th, 2017.
None.
The Daphne dependency requirement was bumped to 1.3.0.
None.
Pending messages correctly handle retries in backlog situations
Pending messages correctly handle retries in backlog situations
Workers in threading mode now respond to ctrl-C and gracefully exit.
request.meta['QUERY_STRING'] is now correctly encoded at all times.
Test client improvements
ChannelServerLiveTestCase added, allows an equivalent of the Django
LiveTestCase.
Decorator added to check Origin headers (allowed_hosts_only)
New TEST_CONFIG setting in CHANNEL_LAYERS that allows varying of
the channel layer for tests (e.g. using a different Redis install)
Channels 1.1.4 is a bugfix release for the 1.1 series, released on June 15th, 2017.
None.
Pending messages correctly handle retries in backlog situations
Workers in threading mode now respond to ctrl-C and gracefully exit.
request.meta['QUERY_STRING'] is now correctly encoded at all times.
Test client improvements
ChannelServerLiveTestCase added, allows an equivalent of the Django LiveTestCase.
Decorator added to check Origin headers (allowed_hosts_only)
New TEST_CONFIG setting in CHANNEL_LAYERS that allows varying of the channel layer for tests (e.g. using a different Redis install)
None.
enforce_ordering now works correctly with the new-style process-specific channels
enforce_ordering now works correctly with the new-style process-specific
channels
ASGI channel layer versions are now explicitly checked for version compatibility
Channels 1.1.3 is a bugfix release for the 1.1 series, released on April 5th, 2017.
None.
enforce_ordering now works correctly with the new-style process-specific channels
ASGI channel layer versions are now explicitly checked for version compatibility
None.
Session name hash changed to SHA-1 to satisfy FIPS-140-2. Due to this, please force all WebSockets to reconnect after the upgrade.
Session name hash changed to SHA-1 to satisfy FIPS-140-2. Due to this, please force all WebSockets to reconnect after the upgrade.
scheme key in ASGI-HTTP messages now translates into request.is_secure()
correctly.
WebsocketBridge now exposes the underlying WebSocket as .socket
Channels 1.1.2 is a bugfix release for the 1.1 series, released on April 1st, 2017.
None.
Session name hash changed to SHA-1 to satisfy FIPS-140-2.
scheme key in ASGI-HTTP messages now translates into request.is_secure() correctly.
WebsocketBridge now exposes the underlying WebSocket as .socket.
When you upgrade all current channel sessions will be invalidated; you should make sure you disconnect all WebSockets during upgrade.
* Fixed JS packaging issue
Channels 1.1.1 is a bugfix release that fixes a packaging issue with the JavaScript files.
None.
The JavaScript binding introduced in 1.1.0 is now correctly packaged and included in builds.
None.
Channels now includes a JavaScript wrapper that wraps reconnection and multiplexing for you on the client side.
Channels now includes a JavaScript wrapper that wraps reconnection and multiplexing for you on the client side.
Test classes have been moved from channels.tests to channels.test.
Bindings now support non-integer fields for primary keys on models.
The enforce_ordering decorator no longer suffers a race condition where
it would drop messages under high load.
runserver no longer errors if the staticfiles app is not enabled in Django.
Channels 1.1.0 introduces a couple of major but backwards-compatible changes, including most notably the inclusion of a standard, framework-agnostic JavaScript library for easier integration with your site.
Channels now includes a JavaScript wrapper that wraps reconnection and multiplexing for you on the client side. For more on how to use it, see the javascript documentation.
Test classes have been moved from channels.tests to channels.test to better match Django. Old imports from channels.tests will continue to work but will trigger a deprecation warning, and channels.tests will be removed completely in version 1.3.
Bindings now support non-integer fields for primary keys on models.
The enforce_ordering decorator no longer suffers a race condition where it would drop messages under high load.
runserver no longer errors if the staticfiles app is not enabled in Django.
None.
Database connections are no longer force-closed after each test is run.
Database connections are no longer force-closed after each test is run.
Channel sessions are not re-saved if they're empty even if they're marked as modified, allowing logout to work correctly.
WebsocketDemultiplexer now correctly does sessions for the second/third/etc. connect and disconnect handlers.
Request reading timeouts now correctly return 408 rather than erroring out.
The rundelay delay server now only polls the database once per second,
and this interval is configurable with the --sleep option.
Channels 1.0.3 is a minor bugfix release, released on 2017/02/01.
Database connections are no longer force-closed after each test is run.
Channel sessions are not re-saved if they're empty even if they're marked as modified, allowing logout to work correctly.
WebsocketDemultiplexer now correctly does sessions for the second/third/etc. connect and disconnect handlers.
Request reading timeouts now correctly return 408 rather than erroring out.
The rundelay delay server now only polls the database once per second, and this interval is configurable with the --sleep option.
None.
Websockets can now be closed from anywhere using the new WebsocketCloseException. There is also a generic ChannelSocketException so you can do custom
Websockets can now be closed from anywhere using the new WebsocketCloseException.
There is also a generic ChannelSocketException so you can do custom behaviours.
Calling Channel.send or Group.send from outside a consumer context
(i.e. in tests or management commands) will once again send the message immediately.
The base implementation of databinding now correctly only calls group_names(instance),
as documented.
Channels 1.0.2 is a minor bugfix release, released on 2017/01/12.
Websockets can now be closed from anywhere using the new WebsocketCloseException, available as channels.exceptions.WebsocketCloseException(code=None). There is also a generic ChannelSocketException you can base any exceptions on that, if it is caught, gets handed the current message in a run method, so you can do custom behaviours.
Calling Channel.send or Group.send from outside a consumer context (i.e. in tests or management commands) will once again send the message immediately, rather than putting it into the consumer message buffer to be flushed when the consumer ends (which never happens)
The base implementation of databinding now correctly only calls group_names(instance), as documented.
None.
WebSocket generic views now accept connections by default in their connect handler for better backwards compatibility.
Channels 1.0.1 is a minor bugfix release, released on 2017/01/09.
WebSocket generic views now accept connections by default in their connect handler for better backwards compatibility.
None.
BREAKING CHANGE: WebSockets must now be explicitly accepted or denied. See https://channels.readthedocs.io/en/latest/releases/1.0.0.html for more.
BREAKING CHANGE: WebSockets must now be explicitly accepted or denied. See https://channels.readthedocs.io/en/latest/releases/1.0.0.html for more.
BREAKING CHANGE: Demultiplexers have been overhauled to directly dispatch messages rather than using channels to new consumers. Consult the docs on generic consumers for more: https://channels.readthedocs.io/en/latest/generics.html
BREAKING CHANGE: Databinding now operates from implicit group membership, where your code just has to say what groups would be used and Channels will work out if it's a creation, modification or removal from a client's perspective, including with permissions.
Delay protocol server ships with Channels providing a specification on how to delay jobs until later and a reference implementation.
Serializers can now specify fields as __all__ to auto-include all fields.
Various other small fixes.
Channels 1.0.0 brings together a number of design changes, including some breaking changes, into our first fully stable release, and also brings the databinding code out of alpha phase. It was released on 2017/01/08.
The result is a faster, easier to use, and safer Channels, including one major change that will fix almost all problems with sessions and connect/receive ordering in a way that needs no persistent storage.
It was unfortunately not possible to make all of the changes backwards compatible, though most code should not be too affected and the fixes are generally quite easy.
You must also update Daphne to at least 1.0.0 to have this release of Channels work correctly.
Channels 1.0 introduces a couple of new major features.
Rather than be immediately accepted, WebSockets now pause during the handshake while they send over a message on websocket.connect, and your application must either accept or reject the connection before the handshake is completed and messages can be received.
You must update Daphne to at least 1.0.0 to make this work correctly.
This has several advantages:
You can now reject WebSockets before they even finish connecting, giving appropriate error codes to browsers and not letting the browser-side socket ever get into a connected state and send messages.
Combined with Consumer Atomicity (below), it means there is no longer any need for the old "slight ordering" mode, as the connect consumer must run to completion and accept the socket before any messages can be received and forwarded onto websocket.receive.
Any send message sent to the WebSocket will implicitly accept the connection, meaning only a limited set of connect consumers need changes (see Backwards Incompatible Changes below)
Consumers will now buffer messages you try to send until the consumer completes and then send them once it exits and the outbound part of any decorators have been run (even if an exception is raised).
This makes the flow of messages much easier to reason about - consumers can now be reasoned about as atomic blocks that run and then send messages, meaning that if you send a message to start another consumer you're guaranteed that the sending consumer has finished running by the time it's acted upon.
If you want to send messages immediately rather than at the end of the consumer, you can still do that by passing the immediately argument:
Channel("thumbnailing-tasks").send({"id": 34245}, immediately=True)
This should be mostly backwards compatible, and may actually fix race conditions in some apps that were pre-existing.
Previously, databinding subclasses had to implement group_names(instance, action) to return what groups to send an instance's change to of the type action. This had flaws, most notably when what was actually just a modification to the instance in question changed its permission status so more clients could see it; to those clients, it should instead have been "created".
Now, Channels just calls group_names(instance), and you should return what groups can see the instance at the current point in time given the instance you were passed. Channels will actually call the method before and after changes, comparing the groups you gave, and sending out create, update or delete messages to clients appropriately.
Existing databinding code will need to be adapted; see the "Backwards Incompatible Changes" section for more.
Demuliplexers have changed to remove the behaviour where they re-sent messages onto new channels without special headers, and instead now correctly split out incoming messages into sub-messages that still look like websocket.receive messages, and directly dispatch these to the relevant consumer.
They also now forward all websocket.connect and websocket.disconnect messages to all of their sub-consumers, so it's much easier to compose things together from code that also works outside the context of multiplexing.
For more, read the updated /generic docs.
A built-in delay server, launched with manage.py rundelay, now ships if you wish to use it. It needs some extra initial setup and uses a database for persistence; see /delay for more information.
Serializers can now specify fields as __all__ to auto-include all fields, and exclude to remove certain unwanted fields.
runserver respects FORCE_SCRIPT_NAME
Websockets can now be closed with a specific code by calling close(status=4000)
enforce_ordering no longer has a slight mode (because of the accept flow changes), and is more efficient with session saving.
runserver respects --nothreading and only launches one worker, takes a --http-timeout option if you want to override it from the default 60,
A new @channel_and_http_session decorator rehydrates the HTTP session out of the channel session if you want to access it inside receive consumers.
Streaming responses no longer have a chance of being cached.
request.META['SERVER_PORT'] is now always a string.
http.disconnect now has a path key so you can route it.
Test client now has a send_and_consume method.
If you have a custom consumer for websocket.connect, you must ensure that it either:
Sends at least one message onto the reply_channel that generates a WebSocket frame (either bytes or text is set), either directly or via a group.
Sends a message onto the reply_channel that is {"accept": True}, to accept a connection without sending data.
Sends a message onto the reply_channel that is {"close": True}, to reject a connection mid-handshake.
Many consumers already do the former, but if your connect consumer does not send anything you MUST now send an accept message or the socket will remain in the handshaking phase forever and you'll never get any messages.
All built-in Channels consumers (e.g. in the generic consumers) have been upgraded to do this.
You must update Daphne to at least 1.0.0 to make this work correctly.
If you have databinding subclasses, you will have implemented group_names(instance, action), which returns the groups to use based on the instance and action provided.
Now, instead, you must implement group_names(instance), which returns the groups that can see the instance as it is presented for you; the action results will be worked out for you. For example, if you want to only show objects marked as "admin_only" to admins, and objects without it to everyone, previously you would have done:
def group_names(self, instance, action):
if instance.admin_only:
return ["admins"]
else:
return ["admins", "non-admins"]
Because you did nothing based on the action (and if you did, you would have got incomplete messages, hence this design change), you can just change the signature of the method like this:
def group_names(self, instance):
if instance.admin_only:
return ["admins"]
else:
return ["admins", "non-admins"]
Now, when an object is updated to have admin_only = True, the clients in the non-admins group will get a delete message, while those in the admins group will get an update message.
Demultiplexers have changed from using a mapping dict, which mapped stream names to channels, to using a consumers dict which maps stream names directly to consumer classes.
You will have to convert over to using direct references to consumers, change the name of the dict, and then you can remove any channel routing for the old channels that were in mapping from your routes.
Additionally, the Demultiplexer now forwards messages as they would look from a direct connection, meaning that where you previously got a decoded object through you will now get a correctly-formatted websocket.receive message through with the content as a text key, JSON-encoded. You will also now have to handle websocket.connect and websocket.disconnect messages.
Both of these issues can be solved using the JsonWebsocketConsumer generic consumer, which will decode for you and correctly separate connection and disconnection handling into their own methods.
channel_session now also rehydrates the http session with an option
channel_session now also rehydrates the http session with an option
request.META['PATH_INFO'] is now present
runserver shows Daphne log messages
runserver --nothreading only starts a single worker thread
Databinding changed to call group_names dynamically and imply changed/created from that; other small changes to databinding, and more changes likely.
New CHANNELS_WS_PROTOCOLS setting if you want Daphne to accept certain subprotocols
New CHANNELS_WS_PROTOCOLS setting if you want Daphne to accept certain subprotocols
WebsocketBindingWithMembers allows serialization of non-fields on instances
Class-based consumers have an .as_route() method that lets you skip using route_class
Bindings now work if loaded after app ready state
Bindings now require that fields is defined on the class body so all fields are not sent by default. To restore old behaviour, set it to ['__all__']
Bindings now require that fields is defined on the class body so all fields
are not sent by default. To restore old behaviour, set it to ['all']
Bindings can now be declared after app.ready() has been called and still work.
Binding payloads now include the model name as appname.modelname.
A worker_ready signal now gets triggered when runworker starts consuming
messages. It does not fire from within runserver.
Data Binding framework is added, which allows easy tying of model changes to WebSockets (and other protocols) and vice-versa.
Data Binding framework is added, which allows easy tying of model changes to WebSockets (and other protocols) and vice-versa.
Standardised WebSocket/JSON multiplexing introduced
WebSocket generic consumers now have a 'close' argument on send/group_send
WebsocketConsumer now has a http_user option for auto user sessions.
WebsocketConsumer now has a http_user option for auto user sessions.
consumer_started and consumer_finished signals are now available under channels.signals.
Database connections are closed whenever a consumer finishes.
websocket.connect and websocket.receive are now consumed by a no-op consumer by default if you don't specify anything to consume it, to bring Channels
websocket.connect and websocket.receive are now consumed by a no-op consumer by default if you don't specify anything to consume it, to bring Channels in line with the ASGI rules on WebSocket backpressure.
You no longer need to call super's setUp in ChannelTestCase.
Class based consumers now have a self.kwargs
Class based consumers now have a self.kwargs
Fixed bug where empty streaming responses did not send headers or status code
Query strings are now decoded entirely by Django. Must be used with Daphne 0.13 or higher.
+ signs in query strings are no longer double-decoded
Message now has .values(), .keys() and .items() to match dict
Class based consumers now have built-in channel_session and channel_session_user support
Fix unicode issues with test client under Python 2.7
Class-based consumer pattern and WebSocket consumer now come with Channels (see docs for more details)
Class-based consumer pattern and WebSocket consumer now come with Channels (see docs for more details)
Better testing utilities including a higher-level Client abstraction with optional HTTP/WebSocket HttpClient variant.
enforce_ordering now queues future messages in a channel rather than spinlocking worker processes to achieve delays.
enforce_ordering now queues future messages in a channel rather than spinlocking worker processes to achieve delays.
ConsumeLater no longer duplicates messages when they're requeued below the limit.
Backpressure is now implemented, meaning responses will pause sending if the client does not read them fast enough.
Backpressure is now implemented, meaning responses will pause sending if the client does not read them fast enough.
DatabaseChannelLayer has been removed; it was not sensible.
HTTP paths and query strings are now expected to be sent over ASGI as unescaped unicode. Daphne 0.11.0 is updated to send things in this format.
HTTP paths and query strings are now expected to be sent over ASGI as unescaped unicode. Daphne 0.11.0 is updated to send things in this format.
request.FILES reading bug fixed
ChannelTestCase base testing class for easier testing of consumers
ChannelTestCase base testing class for easier testing of consumers
Routing rewrite to improve speed with nested includes and remove need for ^ operator
Timeouts reading very slow request bodies
Better error messages for wrongly-constructed routing lists
Better error messages for wrongly-constructed routing lists
Error when trying to use signed cookie backend with channel_session
ASGI group_expiry implemented on database channel backend
Your coding agent can read these notes before it upgrades. Set up the MCP server →