Websockets start as a GET request that can either be upgraded to a
websocket via a 101, switching protocols, response or any other
response. The choice of what to do, or how to respond, is often not
possible in other frameworks and is one of the motivating aims in
Quart. In addition as websockets are very similar to requests, Quart
aims to have analogues functionality between websockets and requests.
Websockets are very similar to GET requests, to the extent that is was
tempting to simply extend the Flask request API to include websocket
functionality. This would likely cause surprise to users of
Flask-Sockets or Flask-SocketIO which set the de-facto Flask
standard. Therefore I decided to introduce the websocket functionality
alongside the existing request functionality.
As websockets are so similar to GET requests it makes sense to produce
an analogue for all the functionality available for requests. For
example. before_request() and
before_websocket() and there is a websocket
context alongside the request context.
The utility of being able to choose how to respond, or whether to
upgrade, is best shown when considering authentication. In the example
below a typical login_required decorator can be used to prevent
unauthorised usage of the websocket.
async def wrapper(*args, **kwargs):
if websocket.authentication == (...):
return await func(*args, **kwargs)
async def ws():
Quart also allows for the acceptance response (101) to be manually
sent via accept() as this gives the
framework user full control.
This functionality is only useable with ASGI servers that
implement the Websocket Denial Response extension. If the
server does not support this extension Quart will instruct the
server to close the connection without a response. Hypercorn, the
recommended ASGI server, supports this extension.
Websocket Denial Response