Skip to content

Commit

Permalink
Deprecate the legacy asyncio implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaugustin committed Sep 22, 2024
1 parent 0ee19be commit 847a88d
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 49 deletions.
12 changes: 3 additions & 9 deletions docs/howto/upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,9 @@ respectively.
.. admonition:: What will happen to the original implementation?
:class: hint

The original implementation is now considered legacy.

The next steps are:

1. Deprecating it once the new implementation is considered sufficiently
robust.
2. Maintaining it for five years per the :ref:`backwards-compatibility
policy <backwards-compatibility policy>`.
3. Removing it. This is expected to happen around 2030.
The original implementation is deprecated. It will be maintained for five
years after deprecation according to the :ref:`backwards-compatibility
policy <backwards-compatibility policy>`. Then, by 2030, it will be removed.

.. _deprecated APIs:

Expand Down
43 changes: 22 additions & 21 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,37 +28,38 @@ with a focus on correctness, simplicity, robustness, and performance.

It supports several network I/O and control flow paradigms.

1. The primary implementation builds upon :mod:`asyncio`, Python's standard
asynchronous I/O framework. It provides an elegant coroutine-based API. It's
ideal for servers that handle many clients concurrently.

.. admonition:: As of version :ref:`13.0`, there is a new :mod:`asyncio`
implementation.
:class: important

The historical implementation in ``websockets.legacy`` traces its roots to
early versions of websockets. Although it's stable and robust, it is now
considered legacy.

The new implementation in ``websockets.asyncio`` is a rewrite on top of
the Sans-I/O implementation. It adds a few features that were impossible
to implement within the original design.

The new implementation provides all features of the historical
implementation, and a few more. If you're using the historical
implementation, you should :doc:`ugrade to the new implementation
<howto/upgrade>`. It's usually straightforward.
1. The default implementation builds upon :mod:`asyncio`, Python's built-in
asynchronous I/O library. It provides an elegant coroutine-based API. It's
ideal for servers that handle many client connections.

2. The :mod:`threading` implementation is a good alternative for clients,
especially if you aren't familiar with :mod:`asyncio`. It may also be used
for servers that don't need to serve many clients.
for servers that handle few client connections.

3. The `Sans-I/O`_ implementation is designed for integrating in third-party
libraries, typically application servers, in addition being used internally
by websockets.

.. _Sans-I/O: https://sans-io.readthedocs.io/

Refer to the :doc:`feature support matrices <reference/features>` for the full
list of features provided by each implementation.

.. admonition:: The :mod:`asyncio` implementation was rewritten.
:class: tip

The new implementation in ``websockets.asyncio`` builds upon the Sans-I/O
implementation. It adds features that were impossible to provide in the
original design. It was introduced in version 13.0.

The historical implementation in ``websockets.legacy`` traces its roots to
early versions of websockets. While it's stable and robust, it was deprecated
in version 14.0 and it will be removed by 2030.

The new implementation provides the same features as the historical
implementation, and then some. If you're using the historical implementation,
you should :doc:`ugrade to the new implementation <howto/upgrade>`.

Here's an echo server using the :mod:`asyncio` API:

.. literalinclude:: ../example/echo.py
Expand Down
3 changes: 3 additions & 0 deletions docs/project/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ Backwards-incompatible changes
.. admonition:: The legacy :mod:`asyncio` implementation is now deprecated.
:class: caution

The :doc:`upgrade guide <../howto/upgrade>` provides complete instructions
to migrate your application.

Aliases for deprecated API were removed from ``__all__``. As a consequence,
they cannot be imported with ``from websockets import *`` anymore. The same
applies to other modules providing aliases.
Expand Down
30 changes: 16 additions & 14 deletions docs/reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,19 @@ Check which implementations support which features and known limitations.

features

:mod:`asyncio` (new)
--------------------
:mod:`asyncio`
--------------

It's ideal for servers that handle many clients concurrently.

It's a rewrite of the legacy :mod:`asyncio` implementation.
This is the default implementation.

.. toctree::
:titlesonly:

asyncio/server
asyncio/client

:mod:`asyncio` (legacy)
-----------------------

This is the historical implementation.

.. toctree::
:titlesonly:

legacy/server
legacy/client

:mod:`threading`
----------------

Expand All @@ -62,6 +51,19 @@ application servers.
sansio/server
sansio/client

:mod:`asyncio` (legacy)
-----------------------

This is the historical implementation.

It is deprecated and will be removed.

.. toctree::
:titlesonly:

legacy/server
legacy/client

Extensions
----------

Expand Down
6 changes: 6 additions & 0 deletions docs/reference/legacy/client.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Client (legacy :mod:`asyncio`)
==============================

.. admonition:: The legacy :mod:`asyncio` implementation is deprecated.
:class: caution

The :doc:`upgrade guide <../../howto/upgrade>` provides complete instructions
to migrate your application.

.. automodule:: websockets.legacy.client

Opening a connection
Expand Down
6 changes: 6 additions & 0 deletions docs/reference/legacy/common.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
Both sides (legacy :mod:`asyncio`)
==================================

.. admonition:: The legacy :mod:`asyncio` implementation is deprecated.
:class: caution

The :doc:`upgrade guide <../../howto/upgrade>` provides complete instructions
to migrate your application.

.. automodule:: websockets.legacy.protocol

.. autoclass:: WebSocketCommonProtocol(*, logger=None, ping_interval=20, ping_timeout=20, close_timeout=10, max_size=2 ** 20, max_queue=2 ** 5, read_limit=2 ** 16, write_limit=2 ** 16)
Expand Down
6 changes: 6 additions & 0 deletions docs/reference/legacy/server.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Server (legacy :mod:`asyncio`)
==============================

.. admonition:: The legacy :mod:`asyncio` implementation is deprecated.
:class: caution

The :doc:`upgrade guide <../../howto/upgrade>` provides complete instructions
to migrate your application.

.. automodule:: websockets.legacy.server

Starting a server
Expand Down
2 changes: 2 additions & 0 deletions docs/topics/design.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
:orphan:

Design (legacy :mod:`asyncio`)
==============================

Expand Down
1 change: 0 additions & 1 deletion docs/topics/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ Get a deeper understanding of how websockets is built and why.
broadcast
compression
keepalive
design
memory
security
performance
11 changes: 8 additions & 3 deletions src/websockets/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

import warnings

from .legacy.auth import *
from .legacy.auth import __all__ # noqa: F401

with warnings.catch_warnings():
# Suppress redundant DeprecationWarning raised by websockets.legacy.
from .legacy.auth import *
from .legacy.auth import __all__ # noqa: F401


warnings.warn( # deprecated in 14.0
"websockets.auth is deprecated",
"websockets.auth, an alias for websockets.legacy.auth, is deprecated; "
"see https://websockets.readthedocs.io/en/stable/howto/upgrade.html "
"for upgrade instructions",
DeprecationWarning,
)
7 changes: 6 additions & 1 deletion src/websockets/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import warnings

from .datastructures import Headers, MultipleValuesError # noqa: F401
from .legacy.http import read_request, read_response # noqa: F401


with warnings.catch_warnings():
# Suppress redundant DeprecationWarning raised by websockets.legacy.
warnings.filterwarnings("ignore", category=DeprecationWarning)
from .legacy.http import read_request, read_response # noqa: F401


warnings.warn( # deprecated in 9.0 - 2021-09-01
Expand Down
11 changes: 11 additions & 0 deletions src/websockets/legacy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from __future__ import annotations

import warnings


warnings.warn( # deprecated in 14.0
"websockets.legacy is deprecated; "
"see https://websockets.readthedocs.io/en/stable/howto/upgrade.html "
"for upgrade instructions",
DeprecationWarning,
)
9 changes: 9 additions & 0 deletions tests/legacy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from __future__ import annotations

import warnings


with warnings.catch_warnings():
# Suppress DeprecationWarning raised by websockets.legacy.
warnings.filterwarnings("ignore", category=DeprecationWarning)
import websockets.legacy # noqa: F401

0 comments on commit 847a88d

Please sign in to comment.