websockets is intended for production use. Therefore, stability is a goal.
websockets also aims at providing the best API for WebSocket in Python.
While we value stability, we value progress more. When an improvement requires changing the API, we make the change and document it below.
When possible with reasonable effort, we preserve backwards-compatibility for five years after the release that introduced the change.
When a release contains backwards-incompatible API changes, the major version is increased, else the minor version is increased. Patch versions are only for fixing regressions shortly after a release.
Version 9.0 moves or deprecates several APIs.
websockets.authwere moved to
Aliases provide backwards compatibility for all previously public APIs.
Added compatibility with Python 3.9.
Added support for IRIs in addition to URIs.
Added close codes 1012, 1013, and 1014.
Fixed sending fragmented, compressed messages.
Hostheader sent when connecting to an IPv6 address.
Fixed starting a Unix server listening on an existing socket.
Aligned maximum cookie size with popular web browsers.
Improved error reporting.
November 1, 2019
Added compatibility with Python 3.8.
July 31, 2019
Restored the ability to pass a socket with the
Removed an incorrect assertion when a connection drops.
July 21, 2019
Restored the ability to import
July 7, 2019
Version 8.0 drops compatibility with Python 3.4 and 3.5.
Version 8.0 expects
process_request to be a coroutine.
Previously, it could be a function or a coroutine.
For backwards compatibility, functions are still mostly supported, but mixing functions and coroutines won’t work in some inheritance scenarios.
Version 8.0 changes the behavior of the
If you were setting
max_queue=0 to make the queue of incoming messages
unbounded, change it to
Version 8.0 deprecates the
port , and
Version 8.0 renames the
WebSocketProtocolError alias provides backwards compatibility.
Version 8.0 adds the reason phrase to the return type of the low-level
basic_auth_protocol_factory()to enforce HTTP Basic Auth on the server side.
connect()handles redirects from the server during the handshake.
unix_connect()for connecting to Unix sockets.
Improved support for sending fragmented messages by accepting asynchronous iterators in
Prevented spurious log messages about
ConnectionClosedexceptions in keepalive ping task. If you were using
ping_timeout=Noneas a workaround, you can remove it.
WebSocketServer.close()to perform a proper closing handshake instead of failing the connection.
Avoided a crash when a
Improved error messages when HTTP parsing fails.
Enabled readline in the interactive client.
Added type hints (PEP 484).
Added a FAQ to the documentation.
Added documentation for extensions.
Documented how to optimize memory usage.
Improved API documentation.
November 1, 2018
websockets now sends Ping frames at regular intervals and closes the
connection if it doesn’t receive a matching Pong frame.
WebSocketCommonProtocol for details.
Version 7.0 changes how a server terminates connections when it’s closed
Previously, connections handlers were canceled. Now, connections are
closed with close code 1001 (going away). From the perspective of the
connection handler, this is the same as if the remote endpoint was
disconnecting. This removes the need to prepare for
CancelledError in connection handlers.
You can restore the previous behavior by adding the following line at the beginning of connection handlers:
def handler(websocket, path): closed = asyncio.ensure_future(websocket.wait_closed()) closed.add_done_callback(lambda task: task.cancel())
This prevents confusion with
For backwards compatibility,
timeout is still supported.
Version 7.0 changes how a
ping() that hasn’t
received a pong yet behaves when the connection is closed.
The ping — as in
ping = await websocket.ping() — used to be canceled
when the connection is closed, so that
await ping raised
await ping raises
ConnectionClosed like other public APIs.
Concurrent calls lead to non-deterministic behavior because there are no guarantees about which coroutine will receive which message.
Added support for sending fragmented messages.
wait_closed()method to protocols.
Added an interactive client:
python -m websockets <uri>.
originsargument to represent the lack of an origin with
Fixed a data loss bug in
recv(): canceling it at the wrong time could result in messages being dropped.
Improved handling of multiple HTTP headers with the same name.
Improved error messages when a required HTTP header is missing.
July 16, 2018
Version 6.0 introduces the
for managing HTTP headers and changes several public APIs:
Functions defined in the
handshakemodule now receive
Headersin argument instead of
set_headerfunctions. This affects libraries that rely on low-level APIs.
Functions defined in the
httpmodule now return HTTP headers as
Headersinstead of lists of
provide similar APIs, this change won’t affect most of the code dealing
with HTTP headers.
Added compatibility with Python 3.7.
May 22, 2018
Version 5.0 fixes a security issue introduced in version 4.0.
Version 4.0 was vulnerable to denial of service by memory exhaustion
because it didn’t enforce
max_size when decompressing compressed
If you’re unpacking
WebSocketURI into four variables, adjust
your code to account for that fifth field.
connect()performs HTTP Basic Auth when the URI contains credentials.
Iterating on incoming messages no longer raises an exception when the connection terminates with close code 1001 (going away).
A plain HTTP request now receives a 426 Upgrade Required response and doesn’t log a stack trace.
unix_serve()can be used as an asynchronous context manager on Python ≥ 3.5.1.
closedproperty to protocols.
ping()doesn’t receive a pong, it’s canceled when the connection is closed.
Reported the cause of
Added new examples in the documentation.
Updated documentation with new features from Python 3.6.
Improved several other sections of the documentation.
Fixed missing close code, which caused
TypeErroron connection close.
Fixed a race condition in the closing handshake that raised
Stopped logging stack traces when the TCP connection dies prematurely.
Prevented writing to a closing TCP connection during unclean shutdowns.
Made connection termination more robust to network congestion.
Prevented processing of incoming frames after failing the connection.
November 2, 2017
Fixed issues with the packaging of the 4.0 release.
November 2, 2017
Version 4.0 drops compatibility with Python 3.3.
Version 4.0 enables compression with the permessage-deflate extension.
In August 2017, Firefox and Chrome support it, but not Safari and IE.
Compression should improve performance but it increases RAM and CPU use.
Version 4.0 removes the
state_name attribute of protocols.
protocol.state.name instead of
WebSocketCommonProtocolinstances can be used as asynchronous iterators on Python ≥ 3.6. They yield incoming messages.
unix_serve()for listening on Unix sockets.
Reorganized and extended documentation.
Aborted connections if they don’t close within the configured
Rewrote connection termination to increase robustness in edge cases.
Stopped leaking pending tasks when
cancel()is called on a connection while it’s being closed.
Reduced verbosity of “Failing the WebSocket connection” logs.
August 20, 2017
serve()can be used as an asynchronous context manager on Python ≥ 3.5.1.
Added support for customizing handling of incoming connections with
Made read and write buffer sizes configurable.
Rewrote HTTP handling for simplicity and performance.
Added an optional C extension to speed up low-level operations.
connect()no longer crashes.
March 29, 2017
Ensured compatibility with Python 3.6.
Reduced noise in logs caused by connection resets.
Avoided crashing on concurrent writes on slow connections.
August 17, 2016
April 21, 2016
Avoided a warning when closing a connection before the opening handshake.
Added flow control for incoming data.
December 25, 2015
Version 3.0 introduces a backwards-incompatible change in the
If you’re upgrading from 2.x or earlier, please read this carefully.
recv() used to return
None when the connection was closed. This required checking the return
value of every call:
message = await websocket.recv() if message is None: return
Now it raises a
ConnectionClosed exception instead.
This is more Pythonic. The previous code can be simplified to:
message = await websocket.recv()
When implementing a server, which is the more popular use case, there’s no strong reason to handle such exceptions. Let them bubble up, terminate the handler coroutine, and the server will simply ignore them.
In order to avoid stranding projects built upon an earlier version, the
previous behavior can be restored by passing
documented in their signatures but isn’t scheduled for deprecation either.
connect()can be used as an asynchronous context manager on Python ≥ 3.5.1.
Updated documentation with
asyncsyntax from Python 3.5.
Worked around an
asynciobug affecting connection termination under load.
state_nameattribute on protocols a public API.
November 18, 2015
Added compatibility with Python 3.5.
August 18, 2015
remote_addressattributes on protocols.
Closed open connections with code 1001 when a server shuts down.
Avoided TCP fragmentation of small frames.
July 28, 2015
Provided access to handshake request and response HTTP headers.
Allowed customizing handshake request and response HTTP headers.
Added support for running on a non-default event loop.
Returned a 403 status code instead of 400 when the request Origin isn’t allowed.
recv()no longer drops the next message.
Clarified that the closing handshake can be initiated by the client.
Set the close code and reason more consistently.
Strengthened connection termination by simplifying the implementation.
Improved tests, added tox configuration, and enforced 100% branch coverage.
November 3, 2014
Improved compliance of close codes.
July 28, 2014
Added support for limiting message size.
April 26, 2014
secureattributes on protocols.
Added support for providing and checking Origin.
February 16, 2014
If you’re upgrading from 1.x or earlier, please read this carefully.
These APIs used to be functions. Now they’re coroutines.
you must now write:
Added flow control for outgoing data.
November 14, 2013
Initial public release.