Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ types:
mypy --strict src

tests:
python -m unittest
python -m unittest tests/sync/test_client.py -v

coverage:
coverage run --source src/websockets,tests -m unittest
Expand Down
13 changes: 13 additions & 0 deletions docs/project/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ notice.

*In development*

New features
............

* Added support for reconnecting automatically by using
:func:`~sync.client.reconnect` as an iterator to the :mod:`threading`
implementation.

* :func:`~sync.client.connect` now follows redirects in the :mod:`threading`
implementation.

* :func:`~sync.client.connect` can connect to another host and port than those
specified in the URI in the :mod:`threading` implementation.

.. _17.0.1:

17.0.1
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ Client
+------------------------------------+--------+--------+--------+--------+--------+
| Close connection on context exit | ✅ | ✅ | ✅ | — | ✅ |
+------------------------------------+--------+--------+--------+--------+--------+
| Reconnect automatically | ✅ | | ✅ | — | ✅ |
| Reconnect automatically | ✅ | | ✅ | — | ✅ |
+------------------------------------+--------+--------+--------+--------+--------+
| Configure ``Origin`` header | ✅ | ✅ | ✅ | ✅ | ✅ |
+------------------------------------+--------+--------+--------+--------+--------+
Expand All @@ -161,7 +161,7 @@ Client
+------------------------------------+--------+--------+--------+--------+--------+
| Connect to non-ASCII IRIs | ✅ | ✅ | ✅ | ✅ | ✅ |
+------------------------------------+--------+--------+--------+--------+--------+
| Follow HTTP redirects | ✅ | | ✅ | — | ✅ |
| Follow HTTP redirects | ✅ | | ✅ | — | ✅ |
+------------------------------------+--------+--------+--------+--------+--------+
| Perform HTTP Basic Authentication | ✅ | ✅ | ✅ | ✅ | ✅ |
+------------------------------------+--------+--------+--------+--------+--------+
Expand Down
6 changes: 6 additions & 0 deletions docs/reference/sync/client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ Opening a connection

.. autofunction:: connect

.. autofunction:: reconnect

.. autofunction:: unix_connect

.. autofunction:: unix_reconnect

.. autofunction:: process_exception

Using a connection
------------------

Expand Down
25 changes: 12 additions & 13 deletions src/websockets/asyncio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,9 @@ class connect:
"""
Connect to the WebSocket server at ``uri``.

This coroutine returns a :class:`ClientConnection` instance, which you can
use to send and receive messages.

:func:`connect` may be used as an asynchronous context manager::
:func:`connect` should be treated as an asynchronous context manager
yielding a :class:`ClientConnection`, which can then receive and send
messages::

from websockets.asyncio.client import connect

Expand All @@ -189,8 +188,8 @@ class connect:

The connection is closed automatically when exiting the context.

:func:`connect` can be used as an infinite asynchronous iterator to
reconnect automatically on errors::
:func:`connect` can also be treated as an infinite asynchronous iterator
to reconnect automatically on errors::

async for websocket in connect(...):
try:
Expand Down Expand Up @@ -555,13 +554,7 @@ def process_redirect(self, exc: Exception) -> Exception | str:

return new_uri

# ... = await connect(...)

def __await__(self) -> Generator[Any, None, ClientConnection]:
# Create a suitable iterator by calling __await__ on a coroutine.
return self.__await_impl__().__await__()

async def __await_impl__(self) -> ClientConnection:
async def connect(self) -> ClientConnection:
try:
async with asyncio.timeout(self.open_timeout):
for _ in range(MAX_REDIRECTS):
Expand Down Expand Up @@ -606,6 +599,12 @@ async def __await_impl__(self) -> ClientConnection:
# Re-raise exception with an informative error message.
raise TimeoutError("timed out during opening handshake") from exc

# ... = await connect(...)

def __await__(self) -> Generator[Any, None, ClientConnection]:
# Create a suitable iterator by calling __await__ on a coroutine.
return self.connect().__await__()

# async with connect(...) as ...: ...

async def __aenter__(self) -> ClientConnection:
Expand Down
Loading