Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
async_simple_client.py210 linesDownload Raw Back to socketio
1import asyncio2from socketio import AsyncClient3from socketio.exceptions import SocketIOError, TimeoutError, DisconnectedError4 5 6class AsyncSimpleClient:7    """A Socket.IO client.8 9    This class implements a simple, yet fully compliant Socket.IO web client10    with support for websocket and long-polling transports.11 12    The positional and keyword arguments given in the constructor are passed13    to the underlying :func:`socketio.AsyncClient` object.14    """15    def __init__(self, *args, **kwargs):16        self.client_args = args17        self.client_kwargs = kwargs18        self.client = None19        self.namespace = '/'20        self.connected_event = asyncio.Event()21        self.connected = False22        self.input_event = asyncio.Event()23        self.input_buffer = []24 25    async def connect(self, url, headers={}, auth=None, transports=None,26                      namespace='/', socketio_path='socket.io',27                      wait_timeout=5):28        """Connect to a Socket.IO server.29 30        :param url: The URL of the Socket.IO server. It can include custom31                    query string parameters if required by the server. If a32                    function is provided, the client will invoke it to obtain33                    the URL each time a connection or reconnection is34                    attempted.35        :param headers: A dictionary with custom headers to send with the36                        connection request. If a function is provided, the37                        client will invoke it to obtain the headers dictionary38                        each time a connection or reconnection is attempted.39        :param auth: Authentication data passed to the server with the40                     connection request, normally a dictionary with one or41                     more string key/value pairs. If a function is provided,42                     the client will invoke it to obtain the authentication43                     data each time a connection or reconnection is attempted.44        :param transports: The list of allowed transports. Valid transports45                           are ``'polling'`` and ``'websocket'``. If not46                           given, the polling transport is connected first,47                           then an upgrade to websocket is attempted.48        :param namespace: The namespace to connect to as a string. If not49                          given, the default namespace ``/`` is used.50        :param socketio_path: The endpoint where the Socket.IO server is51                              installed. The default value is appropriate for52                              most cases.53        :param wait_timeout: How long the client should wait for the54                             connection. The default is 5 seconds.55 56        Note: this method is a coroutine.57        """58        if self.connected:59            raise RuntimeError('Already connected')60        self.namespace = namespace61        self.input_buffer = []62        self.input_event.clear()63        self.client = AsyncClient(*self.client_args, **self.client_kwargs)64 65        @self.client.event(namespace=self.namespace)66        def connect():  # pragma: no cover67            self.connected = True68            self.connected_event.set()69 70        @self.client.event(namespace=self.namespace)71        def disconnect():  # pragma: no cover72            self.connected_event.clear()73 74        @self.client.event(namespace=self.namespace)75        def __disconnect_final():  # pragma: no cover76            self.connected = False77            self.connected_event.set()78 79        @self.client.on('*', namespace=self.namespace)80        def on_event(event, *args):  # pragma: no cover81            self.input_buffer.append([event, *args])82            self.input_event.set()83 84        await self.client.connect(85            url, headers=headers, auth=auth, transports=transports,86            namespaces=[namespace], socketio_path=socketio_path,87            wait_timeout=wait_timeout)88 89    @property90    def sid(self):91        """The session ID received from the server.92 93        The session ID is not guaranteed to remain constant throughout the life94        of the connection, as reconnections can cause it to change.95        """96        return self.client.get_sid(self.namespace) if self.client else None97 98    @property99    def transport(self):100        """The name of the transport currently in use.101 102        The transport is returned as a string and can be one of ``polling``103        and ``websocket``.104        """105        return self.client.transport if self.client else ''106 107    async def emit(self, event, data=None):108        """Emit an event to the server.109 110        :param event: The event name. It can be any string. The event names111                      ``'connect'``, ``'message'`` and ``'disconnect'`` are112                      reserved and should not be used.113        :param data: The data to send to the server. Data can be of114                     type ``str``, ``bytes``, ``list`` or ``dict``. To send115                     multiple arguments, use a tuple where each element is of116                     one of the types indicated above.117 118        Note: this method is a coroutine.119 120        This method schedules the event to be sent out and returns, without121        actually waiting for its delivery. In cases where the client needs to122        ensure that the event was received, :func:`socketio.SimpleClient.call`123        should be used instead.124        """125        while True:126            await self.connected_event.wait()127            if not self.connected:128                raise DisconnectedError()129            try:130                return await self.client.emit(event, data,131                                              namespace=self.namespace)132            except SocketIOError:133                pass134 135    async def call(self, event, data=None, timeout=60):136        """Emit an event to the server and wait for a response.137 138        This method issues an emit and waits for the server to provide a139        response or acknowledgement. If the response does not arrive before the140        timeout, then a ``TimeoutError`` exception is raised.141 142        :param event: The event name. It can be any string. The event names143                      ``'connect'``, ``'message'`` and ``'disconnect'`` are144                      reserved and should not be used.145        :param data: The data to send to the server. Data can be of146                     type ``str``, ``bytes``, ``list`` or ``dict``. To send147                     multiple arguments, use a tuple where each element is of148                     one of the types indicated above.149        :param timeout: The waiting timeout. If the timeout is reached before150                        the server acknowledges the event, then a151                        ``TimeoutError`` exception is raised.152 153        Note: this method is a coroutine.154        """155        while True:156            await self.connected_event.wait()157            if not self.connected:158                raise DisconnectedError()159            try:160                return await self.client.call(event, data,161                                              namespace=self.namespace,162                                              timeout=timeout)163            except SocketIOError:164                pass165 166    async def receive(self, timeout=None):167        """Wait for an event from the server.168 169        :param timeout: The waiting timeout. If the timeout is reached before170                        the server acknowledges the event, then a171                        ``TimeoutError`` exception is raised.172 173        Note: this method is a coroutine.174 175        The return value is a list with the event name as the first element. If176        the server included arguments with the event, they are returned as177        additional list elements.178        """179        while not self.input_buffer:180            try:181                await asyncio.wait_for(self.connected_event.wait(),182                                       timeout=timeout)183            except asyncio.TimeoutError:  # pragma: no cover184                raise TimeoutError()185            if not self.connected:186                raise DisconnectedError()187            try:188                await asyncio.wait_for(self.input_event.wait(),189                                       timeout=timeout)190            except asyncio.TimeoutError:191                raise TimeoutError()192            self.input_event.clear()193        return self.input_buffer.pop(0)194 195    async def disconnect(self):196        """Disconnect from the server.197 198        Note: this method is a coroutine.199        """200        if self.connected:201            await self.client.disconnect()202            self.client = None203            self.connected = False204 205    async def __aenter__(self):206        return self207 208    async def __aexit__(self, exc_type, exc_val, exc_tb):209        await self.disconnect()210 
codekingpro/portable-devtools · Team Ai