Source code for aiohttp._websocket.models

"""Models for WebSocket protocol versions 13 and 8."""

import json
from collections.abc import Callable
from enum import IntEnum
from typing import Any, Final, Literal, NamedTuple, cast

WS_DEFLATE_TRAILING: Final[bytes] = bytes([0x00, 0x00, 0xFF, 0xFF])


[docs] class WSCloseCode(IntEnum): OK = 1000 GOING_AWAY = 1001 PROTOCOL_ERROR = 1002 UNSUPPORTED_DATA = 1003 ABNORMAL_CLOSURE = 1006 INVALID_TEXT = 1007 POLICY_VIOLATION = 1008 MESSAGE_TOO_BIG = 1009 MANDATORY_EXTENSION = 1010 INTERNAL_ERROR = 1011 SERVICE_RESTART = 1012 TRY_AGAIN_LATER = 1013 BAD_GATEWAY = 1014
[docs] class WSMsgType(IntEnum): # websocket spec types CONTINUATION = 0x0 TEXT = 0x1 BINARY = 0x2 PING = 0x9 PONG = 0xA CLOSE = 0x8 # aiohttp specific types CLOSING = 0x100 CLOSED = 0x101 ERROR = 0x102
class WSMessageContinuation(NamedTuple): data: bytes size: int extra: str | None = None type: Literal[WSMsgType.CONTINUATION] = WSMsgType.CONTINUATION class WSMessageText(NamedTuple): data: str size: int extra: str | None = None type: Literal[WSMsgType.TEXT] = WSMsgType.TEXT def json( self, *, loads: Callable[[str | bytes | bytearray], Any] = json.loads ) -> Any: """Return parsed JSON data.""" return loads(self.data) class WSMessageTextBytes(NamedTuple): """WebSocket TEXT message with raw bytes (no UTF-8 decoding).""" data: bytes size: int extra: str | None = None type: Literal[WSMsgType.TEXT] = WSMsgType.TEXT def json(self, *, loads: Callable[[bytes], Any] = json.loads) -> Any: """Return parsed JSON data.""" return loads(self.data) class WSMessageBinary(NamedTuple): data: bytes size: int extra: str | None = None type: Literal[WSMsgType.BINARY] = WSMsgType.BINARY def json( self, *, loads: Callable[[str | bytes | bytearray], Any] = json.loads ) -> Any: """Return parsed JSON data.""" return loads(self.data) class WSMessagePing(NamedTuple): data: bytes size: int extra: str | None = None type: Literal[WSMsgType.PING] = WSMsgType.PING class WSMessagePong(NamedTuple): data: bytes size: int extra: str | None = None type: Literal[WSMsgType.PONG] = WSMsgType.PONG class WSMessageClose(NamedTuple): data: int size: int extra: str | None = None type: Literal[WSMsgType.CLOSE] = WSMsgType.CLOSE class WSMessageClosing(NamedTuple): data: None = None size: int = 0 extra: str | None = None type: Literal[WSMsgType.CLOSING] = WSMsgType.CLOSING class WSMessageClosed(NamedTuple): data: None = None size: int = 0 extra: str | None = None type: Literal[WSMsgType.CLOSED] = WSMsgType.CLOSED class WSMessageError(NamedTuple): data: BaseException size: int = 0 extra: str | None = None type: Literal[WSMsgType.ERROR] = WSMsgType.ERROR # Base message types (excluding TEXT variants) _WSMessageBase = ( WSMessageContinuation | WSMessageBinary | WSMessagePing | WSMessagePong | WSMessageClose | WSMessageClosing | WSMessageClosed | WSMessageError ) # All message types WSMessage = _WSMessageBase | WSMessageText | WSMessageTextBytes # Message type when decode_text=True (default) - TEXT messages have str data WSMessageDecodeText = _WSMessageBase | WSMessageText # Message type when decode_text=False - TEXT messages have bytes data WSMessageNoDecodeText = _WSMessageBase | WSMessageTextBytes WS_CLOSED_MESSAGE = WSMessageClosed() WS_CLOSING_MESSAGE = WSMessageClosing() class WebSocketError(Exception): """WebSocket protocol parser error.""" def __init__(self, code: int, message: str) -> None: self.code = code super().__init__(code, message) def __str__(self) -> str: return cast(str, self.args[1]) class WSHandshakeError(Exception): """WebSocket protocol handshake error."""