### Closing the connection
-* `await websocket.close(code=1000)`
+* `await websocket.close(code=1000, reason=None)`
### Sending and receiving messages
def _raise_on_close(self, message: Message) -> None:
if message["type"] == "websocket.close":
- raise WebSocketDisconnect(message.get("code", 1000))
+ raise WebSocketDisconnect(
+ message.get("code", 1000), message.get("reason", "")
+ )
def send(self, message: Message) -> None:
self._receive_queue.put(message)
class WebSocketDisconnect(Exception):
- def __init__(self, code: int = 1000) -> None:
+ def __init__(self, code: int = 1000, reason: str = None) -> None:
self.code = code
+ self.reason = reason or ""
class WebSocket(HTTPConnection):
else:
await self.send({"type": "websocket.send", "bytes": text.encode("utf-8")})
- async def close(self, code: int = 1000) -> None:
- await self.send({"type": "websocket.close", "code": code})
+ async def close(self, code: int = 1000, reason: str = None) -> None:
+ await self.send(
+ {"type": "websocket.close", "code": code, "reason": reason or ""}
+ )
class WebSocketClose:
- def __init__(self, code: int = 1000) -> None:
+ def __init__(self, code: int = 1000, reason: str = None) -> None:
self.code = code
+ self.reason = reason or ""
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
- await send({"type": "websocket.close", "code": self.code})
+ await send(
+ {"type": "websocket.close", "code": self.code, "reason": self.reason}
+ )
assert websocket == websocket
assert websocket in {websocket}
assert {websocket} == {websocket}
+
+
+def test_websocket_close_reason(test_client_factory) -> None:
+ def app(scope):
+ async def asgi(receive, send):
+ websocket = WebSocket(scope, receive=receive, send=send)
+ await websocket.accept()
+ await websocket.close(code=status.WS_1001_GOING_AWAY, reason="Going Away")
+
+ return asgi
+
+ client = test_client_factory(app)
+ with client.websocket_connect("/") as websocket:
+ with pytest.raises(WebSocketDisconnect) as exc:
+ websocket.receive_text()
+ assert exc.value.code == status.WS_1001_GOING_AWAY
+ assert exc.value.reason == "Going Away"