Source code for wsproto.events

# -*- coding: utf-8 -*-
"""
wsproto/events
~~~~~~~~~~~~~~

Events that result from processing data on a WebSocket connection.
"""


[docs]class Event(object): """ Base class for wsproto events. """ _fields = [] _defaults = {} def __init__(self, **kwargs): allowed = set(self._fields) for kwarg in kwargs: if kwarg not in allowed: raise TypeError( "unrecognized kwarg {} for {}".format( kwarg, self.__class__.__name__ ) ) required = allowed.difference(self._defaults) for field in required: if field not in kwargs: raise TypeError( "missing required kwarg {} for {}".format( field, self.__class__.__name__ ) ) defaults = { key: value() if callable(value) else value for key, value in self._defaults.items() } self.__dict__.update(defaults) self.__dict__.update(kwargs) def __repr__(self): name = self.__class__.__name__ kwarg_strs = [ "{}={}".format(field, self.__dict__[field]) for field in self._fields ] kwarg_str = ", ".join(kwarg_strs) return "{}({})".format(name, kwarg_str) def __eq__(self, other): return self.__class__ == other.__class__ and self.__dict__ == other.__dict__ def __ne__(self, other): return not self.__eq__(other) # This is an unhashable type. __hash__ = None
[docs]class Request(Event): """The beginning of a Websocket connection, the HTTP Upgrade request This event is fired when a SERVER connection receives a WebSocket handshake request (HTTP with upgrade header). Fields: .. attribute:: extensions (Union[List[Extension], List[str]]) .. attribute:: extra_headers The additional request headers, excluding extensions, host, subprotocols, and version headers. .. attribute:: host (str) The hostname, or host header value. .. attribute:: subprotocols List[str] A list of subprotocols ordered by preference. .. attribute:: target (str) A list of the subprotocols proposed in the request, as a list of strings. """ _fields = ["extensions", "extra_headers", "host", "subprotocols", "target"] _defaults = {"extensions": list, "extra_headers": list, "subprotocols": list}
[docs]class AcceptConnection(Event): """The acceptance of a Websocket upgrade request. This event is fired when a CLIENT receives an acceptance response from a server. It is also used to accept an upgrade request when acting as a SERVER. Fields: .. attribute: extra_headers (List[Tuple[bytes, bytes]]) Any additional (non websocket related) headers present in the acceptance response. .. attribute: subprotocol (Optional[str]) The accepted subprotocol to use. Optional. """ _fields = ["extensions", "extra_headers", "subprotocol"] _defaults = {"extensions": list, "extra_headers": list, "subprotocol": None}
[docs]class RejectConnection(Event): """The rejection of a Websocket upgrade request, the HTTP response. This event is fired when a CLIENT receives a rejection response from a server. It can be used to reject a request when sent from as SERVER. If has_body is False the headers must include a content-length or transfer encoding. Fields: .. attribute:: headers (List[Tuple[bytes, bytes]]) The headers to send with the response. .. attribute:: has_body This defaults to False, but set to True if there is a body. See also :class:`~RejectData`. .. attribute:: status_code The response status code. """ _fields = ["headers", "has_body", "status_code"] _defaults = {"headers": list, "has_body": False, "status_code": 400}
[docs]class RejectData(Event): """The rejection HTTP response body. Fields: .. attribute:: body_finished True if this is the final chunk of the body data. .. attribute:: data (bytes) The raw body data. """ _fields = ["body_finished", "data"] _defaults = {"body_finished": True}
[docs]class CloseConnection(Event): """The end of a Websocket connection, represents a closure frame. This event is fired after the connection is considered closed. wsproto automatically emits a CLOSE frame when it receives one, to complete the close-handshake. Fields: .. attribute:: code The integer close code to indicate why the connection has closed. .. attribute:: reason Additional reasoning for why the connection has closed. """ _fields = ["code", "reason"] _defaults = {"reason": None} def response(self): return CloseConnection(code=self.code, reason=self.reason)
[docs]class Message(Event): """The websocket data message. Fields: .. attribute:: data The message data as byte string, can be decoded as UTF-8 for TEXT messages. This only represents a single chunk of data and not a full WebSocket message. You need to buffer and reassemble these chunks to get the full message. .. attribute:: frame_finished This has no semantic content, but is provided just in case some weird edge case user wants to be able to reconstruct the fragmentation pattern of the original stream. .. attribute:: message_finished True if this frame is the last one of this message, False if more frames are expected. """ _fields = ["data", "frame_finished", "message_finished"] _defaults = {"frame_finished": True, "message_finished": True}
[docs]class TextMessage(Message): """This event is fired when a data frame with TEXT payload is received.""" pass
[docs]class BytesMessage(Message): """This event is fired when a data frame with BINARY payload is received. """ pass
[docs]class Ping(Event): """The Ping event can be sent to trigger a ping frame and is fired when a Ping is received. wsproto automatically emits a PONG frame with the same payload. Fields: .. attribute:: payload An optional payload to emit with the ping frame. """ _fields = ["payload"] _defaults = {"payload": b""} def response(self): return Pong(payload=self.payload)
[docs]class Pong(Event): """The Pong event is fired when a Pong is received. Fields: .. attribute:: payload An optional payload to emit with the pong frame. """ _fields = ["payload"] _defaults = {"payload": b""}