Skip to content

Commit

Permalink
Add kwargs to connect() and serve().
Browse files Browse the repository at this point in the history
Reorganize their docstrings for clarity.

Refs #112.
  • Loading branch information
aaugustin committed May 19, 2016
1 parent 1b4f020 commit 9729e63
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 31 deletions.
8 changes: 4 additions & 4 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ Server

.. automodule:: websockets.server

.. autofunction:: serve(ws_handler, host=None, port=None, *, loop=None, klass=WebSocketServerProtocol, origins=None, subprotocols=None, extra_headers=None, **kwds)
.. autofunction:: serve(ws_handler, host=None, port=None, *, klass=WebSocketServerProtocol, timeout=10, max_size=2 ** 20, max_queue=2 ** 5, loop=None, origins=None, subprotocols=None, extra_headers=None, **kwds)

.. autoclass:: WebSocketServerProtocol(ws_handler, ws_server, *, origins=None, subprotocols=None, extra_headers=None, host=None, port=None, secure=None, timeout=10, max_size=2 ** 20, loop=None)
.. autoclass:: WebSocketServerProtocol(ws_handler, ws_server, *, host=None, port=None, secure=None, timeout=10, max_size=2 ** 20, max_queue=2 ** 5, loop=None, origins=None, subprotocols=None, extra_headers=None)

.. automethod:: handshake(origins=None, subprotocols=None, extra_headers=None)
.. automethod:: select_subprotocol(client_protos, server_protos)
Expand All @@ -44,9 +44,9 @@ Client

.. automodule:: websockets.client

.. autofunction:: connect(uri, *, loop=None, klass=WebSocketClientProtocol, origin=None, subprotocols=None, extra_headers=None, **kwds)
.. autofunction:: connect(uri, *, klass=WebSocketClientProtocol, timeout=10, max_size=2 ** 20, max_queue=2 ** 5, loop=None, origin=None, subprotocols=None, extra_headers=None, **kwds)

.. autoclass:: WebSocketClientProtocol(*, host=None, port=None, secure=None, timeout=10, max_size=2 ** 20, loop=None)
.. autoclass:: WebSocketClientProtocol(*, host=None, port=None, secure=None, timeout=10, max_size=2 ** 20, max_queue=2 ** 5, loop=None)

.. automethod:: handshake(wsuri, origin=None, subprotocols=None, extra_headers=None)

Expand Down
3 changes: 3 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Changelog
3.1
...

* Added ``timeout``, ``max_size``, and ``max_queue`` arguments to
:func:`~websockets.client.connect()` and :func:`~websockets.server.serve()`.

This comment has been minimized.

Copy link
@RemiCardona

RemiCardona Jul 4, 2016

Collaborator

Surely you meant to add this to a 3.2 section ? :)

This comment has been minimized.

Copy link
@aaugustin

aaugustin Jul 4, 2016

Author Member

Oops. Fixed. Thanks.

* Avoided a warning when closing a connection before the opening handshake.

* Added flow control for incoming data.
Expand Down
34 changes: 22 additions & 12 deletions websockets/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,36 +101,44 @@ def handshake(self, wsuri,

@asyncio.coroutine
def connect(uri, *,
loop=None, klass=WebSocketClientProtocol, legacy_recv=False,
klass=WebSocketClientProtocol,
timeout=10, max_size=2 ** 20, max_queue=2 ** 5,
loop=None, legacy_recv=False,
origin=None, subprotocols=None, extra_headers=None,
**kwds):
"""
This coroutine connects to a WebSocket server.
This coroutine connects to a WebSocket server at a given ``uri``.
It's a wrapper around the event loop's
It yields a :class:`WebSocketClientProtocol` which can then be used to
send and receive messages.
:func:`connect` is a wrapper around the event loop's
:meth:`~asyncio.BaseEventLoop.create_connection` method. Extra keyword
arguments are passed to :meth:`~asyncio.BaseEventLoop.create_connection`.
For example, you can set the ``ssl`` keyword argument to a
:class:`~ssl.SSLContext` to enforce some TLS settings. When connecting to
a ``wss://`` URI, if this argument isn't provided explicitly, it's set to
``True``, which means Python's default :class:`~ssl.SSLContext` is used.
:func:`connect` accepts several optional arguments:
The behavior of the ``timeout``, ``max_size``, and ``max_queue`` optional
arguments is described the documentation of
:class:`~websockets.protocol.WebSocketCommonProtocol`.
:func:`connect` also accepts the following optional arguments:
* ``origin`` sets the Origin HTTP header
* ``subprotocols`` is a list of supported subprotocols in order of
decreasing preference
* ``extra_headers`` sets additional HTTP request headers – it can be a
mapping or an iterable of (name, value) pairs
:func:`connect` yields a :class:`WebSocketClientProtocol` which can then
be used to send and receive messages.
It raises :exc:`~websockets.uri.InvalidURI` if ``uri`` is invalid and
:exc:`~websockets.handshake.InvalidHandshake` if the handshake fails.
:func:`connect` raises :exc:`~websockets.uri.InvalidURI` if ``uri`` is
invalid and :exc:`~websockets.handshake.InvalidHandshake` if the opening
handshake fails.
On Python 3.5, it can be used as a asynchronous context manager. In that
case, the connection is closed when exiting the context.
On Python 3.5, :func:`connect` can be used as a asynchronous context
manager. In that case, the connection is closed when exiting the context.
"""
if loop is None:
Expand All @@ -144,7 +152,9 @@ def connect(uri, *,
"Use a wss:// URI to enable TLS.")
factory = lambda: klass(
host=wsuri.host, port=wsuri.port, secure=wsuri.secure,
loop=loop, legacy_recv=legacy_recv)
timeout=timeout, max_size=max_size, max_queue=max_queue,
loop=loop, legacy_recv=legacy_recv,
)

transport, protocol = yield from loop.create_connection(
factory, wsuri.host, wsuri.port, **kwds)
Expand Down
41 changes: 26 additions & 15 deletions websockets/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,22 +245,37 @@ def wait_closed(self):

@asyncio.coroutine
def serve(ws_handler, host=None, port=None, *,
loop=None, klass=WebSocketServerProtocol, legacy_recv=False,
klass=WebSocketServerProtocol,
timeout=10, max_size=2 ** 20, max_queue=2 ** 5,
loop=None, legacy_recv=False,
origins=None, subprotocols=None, extra_headers=None,
**kwds):
"""
This coroutine creates a WebSocket server.
It's a wrapper around the event loop's
:meth:`~asyncio.BaseEventLoop.create_server` method. ``host``, ``port`` as
well as extra keyword arguments are passed to
:meth:`~asyncio.BaseEventLoop.create_server`. For example, you can set the
``ssl`` keyword argument to a :class:`~ssl.SSLContext` to enable TLS.
It yields a :class:`~asyncio.Server` which provides:
* a :meth:`~asyncio.Server.close` method that closes open connections with
status code 1001 and stops accepting new connections
* a :meth:`~asyncio.Server.wait_closed` coroutine that waits until closing
handshakes complete and connections are closed.
``ws_handler`` is the WebSocket handler. It must be a coroutine accepting
two arguments: a :class:`WebSocketServerProtocol` and the request URI.
:func:`serve` accepts several optional arguments:
:func:`serve` is a wrapper around the event loop's
:meth:`~asyncio.BaseEventLoop.create_server` method. ``host``, ``port`` as
well as extra keyword arguments are passed to
:meth:`~asyncio.BaseEventLoop.create_server`.
For example, you can set the ``ssl`` keyword argument to a
:class:`~ssl.SSLContext` to enable TLS.
The behavior of the ``timeout``, ``max_size``, and ``max_queue`` optional
arguments is described the documentation of
:class:`~websockets.protocol.WebSocketCommonProtocol`.
:func:`serve` also accepts the following optional arguments:
* ``origins`` defines acceptable Origin HTTP headers — include
``''`` if the lack of an origin is acceptable
Expand All @@ -270,13 +285,6 @@ def serve(ws_handler, host=None, port=None, *,
mapping, an iterable of (name, value) pairs, or a callable taking the
request path and headers in arguments.
:func:`serve` yields a :class:`~asyncio.Server` which provides:
* a :meth:`~asyncio.Server.close` method that closes open connections with
status code 1001 and stops accepting new connections
* a :meth:`~asyncio.Server.wait_closed` coroutine that waits until closing
handshakes complete and connections are closed.
Whenever a client connects, the server accepts the connection, creates a
:class:`WebSocketServerProtocol`, performs the opening handshake, and
delegates to the WebSocket handler. Once the handler completes, the server
Expand All @@ -301,8 +309,11 @@ def serve(ws_handler, host=None, port=None, *,
factory = lambda: klass(
ws_handler, ws_server,
host=host, port=port, secure=secure,
timeout=timeout, max_size=max_size, max_queue=max_queue,
loop=loop, legacy_recv=legacy_recv,
origins=origins, subprotocols=subprotocols,
extra_headers=extra_headers, loop=loop, legacy_recv=legacy_recv)
extra_headers=extra_headers,
)
server = yield from loop.create_server(factory, host, port, **kwds)

ws_server.wrap(server)
Expand Down

0 comments on commit 9729e63

Please sign in to comment.