Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
events.py296 linesDownload Raw Back to wsproto
1"""2wsproto/events3~~~~~~~~~~~~~~4 5Events that result from processing data on a WebSocket connection.6"""7from abc import ABC8from dataclasses import dataclass, field9from typing import Generic, List, Optional, Sequence, TypeVar, Union10 11from .extensions import Extension12from .typing import Headers13 14 15class Event(ABC):16    """17    Base class for wsproto events.18    """19 20    pass  # noqa21 22 23@dataclass(frozen=True)24class Request(Event):25    """The beginning of a Websocket connection, the HTTP Upgrade request26 27    This event is fired when a SERVER connection receives a WebSocket28    handshake request (HTTP with upgrade header).29 30    Fields:31 32    .. attribute:: host33 34       (Required) The hostname, or host header value.35 36    .. attribute:: target37 38       (Required) The request target (path and query string)39 40    .. attribute:: extensions41 42       The proposed extensions.43 44    .. attribute:: extra_headers45 46       The additional request headers, excluding extensions, host, subprotocols,47       and version headers.48 49    .. attribute:: subprotocols50 51       A list of the subprotocols proposed in the request, as a list52       of strings.53    """54 55    host: str56    target: str57    extensions: Union[Sequence[Extension], Sequence[str]] = field(  # type: ignore[assignment]58        default_factory=list59    )60    extra_headers: Headers = field(default_factory=list)61    subprotocols: List[str] = field(default_factory=list)62 63 64@dataclass(frozen=True)65class AcceptConnection(Event):66    """The acceptance of a Websocket upgrade request.67 68    This event is fired when a CLIENT receives an acceptance response69    from a server. It is also used to accept an upgrade request when70    acting as a SERVER.71 72    Fields:73 74    .. attribute:: extra_headers75 76       Any additional (non websocket related) headers present in the77       acceptance response.78 79    .. attribute:: subprotocol80 81       The accepted subprotocol to use.82 83    """84 85    subprotocol: Optional[str] = None86    extensions: List[Extension] = field(default_factory=list)87    extra_headers: Headers = field(default_factory=list)88 89 90@dataclass(frozen=True)91class RejectConnection(Event):92    """The rejection of a Websocket upgrade request, the HTTP response.93 94    The ``RejectConnection`` event sends the appropriate HTTP headers to95    communicate to the peer that the handshake has been rejected. You may also96    send an HTTP body by setting the ``has_body`` attribute to ``True`` and then97    sending one or more :class:`RejectData` events after this one. When sending98    a response body, the caller should set the ``Content-Length``,99    ``Content-Type``, and/or ``Transfer-Encoding`` headers as appropriate.100 101    When receiving a ``RejectConnection`` event, the ``has_body`` attribute will102    in almost all cases be ``True`` (even if the server set it to ``False``) and103    will be followed by at least one ``RejectData`` events, even though the data104    itself might be just ``b""``. (The only scenario in which the caller105    receives a ``RejectConnection`` with ``has_body == False`` is if the peer106    violates sends an informational status code (1xx) other than 101.)107 108    The ``has_body`` attribute should only be used when receiving the event. (It109    has ) is False the headers must include a110    content-length or transfer encoding.111 112    Fields:113 114    .. attribute:: headers (Headers)115 116       The headers to send with the response.117 118    .. attribute:: has_body119 120       This defaults to False, but set to True if there is a body. See121       also :class:`~RejectData`.122 123    .. attribute:: status_code124 125       The response status code.126 127    """128 129    status_code: int = 400130    headers: Headers = field(default_factory=list)131    has_body: bool = False132 133 134@dataclass(frozen=True)135class RejectData(Event):136    """The rejection HTTP response body.137 138    The caller may send multiple ``RejectData`` events. The final event should139    have the ``body_finished`` attribute set to ``True``.140 141    Fields:142 143    .. attribute:: body_finished144 145       True if this is the final chunk of the body data.146 147    .. attribute:: data (bytes)148 149       (Required) The raw body data.150 151    """152 153    data: bytes154    body_finished: bool = True155 156 157@dataclass(frozen=True)158class CloseConnection(Event):159 160    """The end of a Websocket connection, represents a closure frame.161 162    **wsproto does not automatically send a response to a close event.** To163    comply with the RFC you MUST send a close event back to the remote WebSocket164    if you have not already sent one. The :meth:`response` method provides a165    suitable event for this purpose, and you should check if a response needs166    to be sent by checking :func:`wsproto.WSConnection.state`.167 168    Fields:169 170    .. attribute:: code171 172       (Required) The integer close code to indicate why the connection173       has closed.174 175    .. attribute:: reason176 177       Additional reasoning for why the connection has closed.178 179    """180 181    code: int182    reason: Optional[str] = None183 184    def response(self) -> "CloseConnection":185        """Generate an RFC-compliant close frame to send back to the peer."""186        return CloseConnection(code=self.code, reason=self.reason)187 188 189T = TypeVar("T", bytes, str)190 191 192@dataclass(frozen=True)193class Message(Event, Generic[T]):194    """The websocket data message.195 196    Fields:197 198    .. attribute:: data199 200       (Required) The message data as byte string, can be decoded as UTF-8 for201       TEXT messages.  This only represents a single chunk of data and202       not a full WebSocket message.  You need to buffer and203       reassemble these chunks to get the full message.204 205    .. attribute:: frame_finished206 207       This has no semantic content, but is provided just in case some208       weird edge case user wants to be able to reconstruct the209       fragmentation pattern of the original stream.210 211    .. attribute:: message_finished212 213       True if this frame is the last one of this message, False if214       more frames are expected.215 216    """217 218    data: T219    frame_finished: bool = True220    message_finished: bool = True221 222 223@dataclass(frozen=True)224class TextMessage(Message[str]):  # pylint: disable=unsubscriptable-object225    """This event is fired when a data frame with TEXT payload is received.226 227    Fields:228 229    .. attribute:: data230 231       The message data as string, This only represents a single chunk232       of data and not a full WebSocket message.  You need to buffer233       and reassemble these chunks to get the full message.234 235    """236 237    # https://github.com/python/mypy/issues/5744238    data: str239 240 241@dataclass(frozen=True)242class BytesMessage(Message[bytes]):  # pylint: disable=unsubscriptable-object243    """This event is fired when a data frame with BINARY payload is244    received.245 246    Fields:247 248    .. attribute:: data249 250       The message data as byte string, can be decoded as UTF-8 for251       TEXT messages.  This only represents a single chunk of data and252       not a full WebSocket message.  You need to buffer and253       reassemble these chunks to get the full message.254    """255 256    # https://github.com/python/mypy/issues/5744257    data: bytes258 259 260@dataclass(frozen=True)261class Ping(Event):262    """The Ping event can be sent to trigger a ping frame and is fired263    when a Ping is received.264 265    **wsproto does not automatically send a pong response to a ping event.** To266    comply with the RFC you MUST send a pong even as soon as is practical. The267    :meth:`response` method provides a suitable event for this purpose.268 269    Fields:270 271    .. attribute:: payload272 273       An optional payload to emit with the ping frame.274    """275 276    payload: bytes = b""277 278    def response(self) -> "Pong":279        """Generate an RFC-compliant :class:`Pong` response to this ping."""280        return Pong(payload=self.payload)281 282 283@dataclass(frozen=True)284class Pong(Event):285    """The Pong event is fired when a Pong is received.286 287    Fields:288 289    .. attribute:: payload290 291       An optional payload to emit with the pong frame.292 293    """294 295    payload: bytes = b""296 
codekingpro/portable-devtools · Team Ai