python-socketio 5.16.1__py3-none-any.whl → 5.16.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-socketio
3
- Version: 5.16.1
3
+ Version: 5.16.3
4
4
  Summary: Socket.IO server and client for Python
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  License: MIT
@@ -14,7 +14,7 @@ Requires-Python: >=3.8
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
16
  Requires-Dist: bidict>=0.21.0
17
- Requires-Dist: python-engineio>=4.11.0
17
+ Requires-Dist: python-engineio>=4.13.2
18
18
  Provides-Extra: client
19
19
  Requires-Dist: requests>=2.21.0; extra == "client"
20
20
  Requires-Dist: websocket-client>=0.54.0; extra == "client"
@@ -1,15 +1,15 @@
1
- python_socketio-5.16.1.dist-info/licenses/LICENSE,sha256=yel9Pbwfu82094CLKCzWRtuIev9PUxP-a76NTDFAWpw,1082
1
+ python_socketio-5.16.3.dist-info/licenses/LICENSE,sha256=yel9Pbwfu82094CLKCzWRtuIev9PUxP-a76NTDFAWpw,1082
2
2
  socketio/__init__.py,sha256=DXxtwPIqHFIqV4BGTgJ86OvCXD6Mth3PxBYhFoJ1_7g,1269
3
3
  socketio/admin.py,sha256=Ag0fz2QRVq5mprjkBe9txNjGPvQEpBai6-VJ-rJsxmA,16260
4
4
  socketio/asgi.py,sha256=NaJtYhOswVVcwHU0zcMM5H5TrSzXq9K-CAYaeSNTZRY,2192
5
5
  socketio/async_admin.py,sha256=4DFriPI3lwjgV80a81x1tndmQcRuYJGIu0wwkNS9ayY,16471
6
- socketio/async_aiopika_manager.py,sha256=X3PQrPMpJdu0yF8EoqvjB7lTb1wyAe4-EI1ToSuHiaA,5892
6
+ socketio/async_aiopika_manager.py,sha256=zvP5FqHMgp3PZEHmtjKQm_LzhP1DWle_1M1EmLYS-n8,6037
7
7
  socketio/async_client.py,sha256=Xa9R2LJz6enF94TbfzPl7m2BMikLcqZl6AAZDyIHlZo,28124
8
8
  socketio/async_manager.py,sha256=G7TLqCDVozbHt0ODG3jU09h1ku6ahk87_Sz4Cm5tL90,4518
9
9
  socketio/async_namespace.py,sha256=BxSUs_iQzPHFo6JyoRZm2Yy0uRyizvS2PMCIzsVzk_o,12043
10
10
  socketio/async_pubsub_manager.py,sha256=UwU_i_cDvJ4vRzB6RnefEFuWKoiL35WgXHR0y2-CXas,12474
11
- socketio/async_redis_manager.py,sha256=S_S09BCeyr8N_Ma6ickbDuKESvPaKSYTSXAjd73OMPo,7848
12
- socketio/async_server.py,sha256=7_AVMhfZFPaJ5t3nZxaoBT_-Sl1FmDA8A46oXOrXE74,36669
11
+ socketio/async_redis_manager.py,sha256=E0w4gDgrZnEUu5jCatf-P5F-wQvjr2673viEf8zr3pQ,7555
12
+ socketio/async_server.py,sha256=nU-QMFiTk1i2WrLaxiUGJuHmfFnXPvpxHhMFcqC2JuM,36968
13
13
  socketio/async_simple_client.py,sha256=eZUgU9fz7c9lXhsbm4Ln95dinM9zxT3Ps2sML4HtT6Y,9016
14
14
  socketio/base_client.py,sha256=LJzYynrxPuId7xbHAWiTPFlEAROQCLi8cOmiIDuc1Lk,11673
15
15
  socketio/base_manager.py,sha256=w4JZrUSpQ8Unsy0ZwQmEEXwvSzeCGT3AfR0ma0Tmczo,6116
@@ -18,19 +18,19 @@ socketio/base_server.py,sha256=JtHtmxFjtclcdORg7FIBoMtMxiaCFnuwulXrpLUSjUE,10637
18
18
  socketio/client.py,sha256=ttcjNZ-Qb1yUKjb2Eiylw02wt6ghTXWalfw_y7ODNRo,26355
19
19
  socketio/exceptions.py,sha256=c8yKss_oJl-fkL52X_AagyJecL-9Mxlgb5xDRqSz5tA,975
20
20
  socketio/kafka_manager.py,sha256=QrgTh94Ft2YmQbJ_uVX9HMotKWZYBfWh6Y66RYrSwtM,3114
21
- socketio/kombu_manager.py,sha256=EAwW-_L-FCQTWeZjpjE0xqJt5RZSUBdQwU7ASORyaNg,6468
21
+ socketio/kombu_manager.py,sha256=3nLyVPrJyeKLi0E2jp0I33W3EYXDkR89mCmW0FtrBmk,6581
22
22
  socketio/manager.py,sha256=RPYPcVBFAjN-fEtLfcsPlk6SOW_SBATvw0Tkq_PkGZw,3861
23
23
  socketio/middleware.py,sha256=P8wOgSzy3YKOcRVI-r3KNKsEejBz_f5p2wdV8ZqW12E,1591
24
24
  socketio/msgpack_packet.py,sha256=gSLKgYP88QAJ1J8sOmgGFvtRBmNH8QWPtHImWaXIqzs,1765
25
25
  socketio/namespace.py,sha256=80y8BN2FFlHK8JKF1TirWvvE4pn9FkGKk14IVFkCLEs,9488
26
26
  socketio/packet.py,sha256=N7jEjcqOUg2PPEooCoEglxVxhjRqJF-FZCPyDF-UDKQ,7120
27
27
  socketio/pubsub_manager.py,sha256=3xUqRnHiFVf_YI68OWRakJTa2LGHPpyMZNSAQN43GZY,11775
28
- socketio/redis_manager.py,sha256=_I8n5GJcYWlSnmYZnADDfvn4FP2BMfllHqN4JYuuYeE,8923
29
- socketio/server.py,sha256=ciEtM1mmXP99zOs5i8kHEPe3uXytYSFNQPRnfTE466s,35042
28
+ socketio/redis_manager.py,sha256=5MhbV4DWJtazxvEgAF_fmAVj-a_F6xhFhq9cpX-_V2I,8734
29
+ socketio/server.py,sha256=cNDOBJ8u01D0ttZmcrUM0vN-1rT8Z1D_-oMMOnEWGWU,35341
30
30
  socketio/simple_client.py,sha256=aSMTRO8LHBAWO2IV9uetL6_zwZgPGR-ts73x_4k3624,8434
31
31
  socketio/tornado.py,sha256=R82JCqz-E1ibZAQX708h7FX3sguCHQ1OLYpnMag-LY8,295
32
32
  socketio/zmq_manager.py,sha256=PkY5aP7-JesCJjumRht90pf3dqLGZV1WrGZ5lA8jQ-Y,4232
33
- python_socketio-5.16.1.dist-info/METADATA,sha256=aKRBDNDXnim5rhevWwXO_7swzXof2LRiSJr3zGEeqDM,3281
34
- python_socketio-5.16.1.dist-info/WHEEL,sha256=YLJXdYXQ2FQ0Uqn2J-6iEIC-3iOey8lH3xCtvFLkd8Q,91
35
- python_socketio-5.16.1.dist-info/top_level.txt,sha256=xWd-HVUanhys_VzQQTRTRZBX8W448ayFytYf1Zffivs,9
36
- python_socketio-5.16.1.dist-info/RECORD,,
33
+ python_socketio-5.16.3.dist-info/METADATA,sha256=Sh2h28lDLOA2zYOvS6I-_7Bn4hEFvMIfn1rPSrdyJ98,3281
34
+ python_socketio-5.16.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
35
+ python_socketio-5.16.3.dist-info/top_level.txt,sha256=xWd-HVUanhys_VzQQTRTRZBX8W448ayFytYf1Zffivs,9
36
+ python_socketio-5.16.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (81.0.0)
2
+ Generator: setuptools (82.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -97,18 +97,20 @@ class AsyncAioPikaManager(AsyncPubSubManager): # pragma: no cover
97
97
  ), routing_key='*',
98
98
  )
99
99
  break
100
- except aio_pika.AMQPException:
100
+ except aio_pika.exceptions.ChannelInvalidStateError:
101
+ # aio_pika raises this exception when the task is cancelled
102
+ raise asyncio.CancelledError()
103
+ except Exception as exc:
101
104
  if retry:
102
- self._get_logger().error('Cannot publish to rabbitmq... '
103
- 'retrying')
105
+ self._get_logger().error(
106
+ 'Cannot publish to rabbitmq... retrying',
107
+ extra={"rabbitmq_exception": str(exc)})
104
108
  retry = False
105
109
  else:
106
110
  self._get_logger().error(
107
- 'Cannot publish to rabbitmq... giving up')
111
+ 'Cannot publish to rabbitmq... giving up',
112
+ extra={"rabbitmq_exception": str(exc)})
108
113
  break
109
- except aio_pika.exceptions.ChannelInvalidStateError:
110
- # aio_pika raises this exception when the task is cancelled
111
- raise asyncio.CancelledError()
112
114
 
113
115
  async def _listen(self):
114
116
  retry_sleep = 1
@@ -125,12 +127,13 @@ class AsyncAioPikaManager(AsyncPubSubManager): # pragma: no cover
125
127
  async with message.process():
126
128
  yield message.body
127
129
  retry_sleep = 1
128
- except aio_pika.AMQPException:
129
- self._get_logger().error(
130
- 'Cannot receive from rabbitmq... '
131
- 'retrying in {} secs'.format(retry_sleep))
132
- await asyncio.sleep(retry_sleep)
133
- retry_sleep = min(retry_sleep * 2, 60)
134
130
  except aio_pika.exceptions.ChannelInvalidStateError:
135
131
  # aio_pika raises this exception when the task is cancelled
136
132
  raise asyncio.CancelledError()
133
+ except Exception as exc:
134
+ self._get_logger().error(
135
+ 'Cannot receive from rabbotmq... retrying in '
136
+ f'{retry_sleep} secs',
137
+ extra={"rabbitmq_exception": str(exc)})
138
+ await asyncio.sleep(retry_sleep)
139
+ retry_sleep = min(retry_sleep * 2, 60)
@@ -75,7 +75,7 @@ class AsyncRedisManager(AsyncPubSubManager):
75
75
  self.redis = None
76
76
  self.pubsub = None
77
77
 
78
- def _get_redis_module_and_error(self):
78
+ def _get_redis_module(self):
79
79
  parsed_url = urlparse(self.redis_url)
80
80
  scheme = parsed_url.scheme.split('+', 1)[0].lower()
81
81
  if scheme in ['redis', 'rediss']:
@@ -83,13 +83,13 @@ class AsyncRedisManager(AsyncPubSubManager):
83
83
  raise RuntimeError('Redis package is not installed '
84
84
  '(Run "pip install redis" '
85
85
  'in your virtualenv).')
86
- return aioredis, RedisError
86
+ return aioredis
87
87
  if scheme in ['valkey', 'valkeys']:
88
88
  if aiovalkey is None or ValkeyError is None:
89
89
  raise RuntimeError('Valkey package is not installed '
90
90
  '(Run "pip install valkey" '
91
91
  'in your virtualenv).')
92
- return aiovalkey, ValkeyError
92
+ return aiovalkey
93
93
  if scheme == 'unix':
94
94
  if aioredis is None or RedisError is None:
95
95
  if aiovalkey is None or ValkeyError is None:
@@ -98,14 +98,14 @@ class AsyncRedisManager(AsyncPubSubManager):
98
98
  'or "pip install valkey" '
99
99
  'in your virtualenv).')
100
100
  else:
101
- return aiovalkey, ValkeyError
101
+ return aiovalkey
102
102
  else:
103
- return aioredis, RedisError
103
+ return aioredis
104
104
  error_msg = f'Unsupported Redis URL scheme: {scheme}'
105
105
  raise ValueError(error_msg)
106
106
 
107
107
  def _redis_connect(self):
108
- module, _ = self._get_redis_module_and_error()
108
+ module = self._get_redis_module()
109
109
  parsed_url = urlparse(self.redis_url)
110
110
  if parsed_url.scheme in {"redis+sentinel", "valkey+sentinel"}:
111
111
  sentinels, service_name, connection_kwargs = \
@@ -121,30 +121,25 @@ class AsyncRedisManager(AsyncPubSubManager):
121
121
  self.connected = True
122
122
 
123
123
  async def _publish(self, data): # pragma: no cover
124
- _, error = self._get_redis_module_and_error()
125
124
  for retries_left in range(1, -1, -1): # 2 attempts
126
125
  try:
127
126
  if not self.connected:
128
127
  self._redis_connect()
129
128
  return await self.redis.publish(
130
129
  self.channel, self.json.dumps(data))
131
- except error as exc:
130
+ except Exception as exc:
132
131
  if retries_left > 0:
133
132
  self._get_logger().error(
134
- 'Cannot publish to redis... '
135
- 'retrying',
133
+ 'Cannot publish to redis... retrying',
136
134
  extra={"redis_exception": str(exc)})
137
135
  self.connected = False
138
136
  else:
139
137
  self._get_logger().error(
140
- 'Cannot publish to redis... '
141
- 'giving up',
138
+ 'Cannot publish to redis... giving up',
142
139
  extra={"redis_exception": str(exc)})
143
-
144
140
  break
145
141
 
146
142
  async def _redis_listen_with_retries(self): # pragma: no cover
147
- _, error = self._get_redis_module_and_error()
148
143
  retry_sleep = 1
149
144
  subscribed = False
150
145
  while True:
@@ -155,11 +150,11 @@ class AsyncRedisManager(AsyncPubSubManager):
155
150
  retry_sleep = 1
156
151
  async for message in self.pubsub.listen():
157
152
  yield message
158
- except error as exc:
159
- self._get_logger().error('Cannot receive from redis... '
160
- 'retrying in '
161
- f'{retry_sleep} secs',
162
- extra={"redis_exception": str(exc)})
153
+ except Exception as exc:
154
+ self._get_logger().error(
155
+ 'Cannot receive from redis... retrying in '
156
+ f'{retry_sleep} secs',
157
+ extra={"redis_exception": str(exc)})
163
158
  subscribed = False
164
159
  await asyncio.sleep(retry_sleep)
165
160
  retry_sleep *= 2
socketio/async_server.py CHANGED
@@ -427,6 +427,8 @@ class AsyncServer(base_server.BaseServer):
427
427
  if delete_it:
428
428
  self.logger.info('Disconnecting %s [%s]', sid, namespace)
429
429
  eio_sid = self.manager.pre_disconnect(sid, namespace=namespace)
430
+ if eio_sid in self._binary_packet:
431
+ del self._binary_packet[eio_sid]
430
432
  await self._send_packet(eio_sid, self.packet_class(
431
433
  packet.DISCONNECT, namespace=namespace))
432
434
  await self._trigger_event('disconnect', namespace, sid,
@@ -702,6 +704,9 @@ class AsyncServer(base_server.BaseServer):
702
704
  pkt.data)
703
705
  elif pkt.packet_type == packet.BINARY_EVENT or \
704
706
  pkt.packet_type == packet.BINARY_ACK:
707
+ if not self.manager.sid_from_eio_sid(eio_sid,
708
+ pkt.namespace or '/'):
709
+ raise ValueError('Unexpected binary packet')
705
710
  self._binary_packet[eio_sid] = pkt
706
711
  elif pkt.packet_type == packet.CONNECT_ERROR:
707
712
  raise ValueError('Unexpected CONNECT_ERROR packet.')
socketio/kombu_manager.py CHANGED
@@ -114,14 +114,16 @@ class KombuManager(PubSubManager): # pragma: no cover
114
114
  self.publisher_connection)
115
115
  producer_publish(self.json.dumps(data))
116
116
  break
117
- except (OSError, kombu.exceptions.KombuError):
117
+ except Exception as exc:
118
118
  if retry:
119
- self._get_logger().error('Cannot publish to rabbitmq... '
120
- 'retrying')
119
+ self._get_logger().error(
120
+ 'Cannot publish to rabbitmq... retrying',
121
+ extra={"rabbitmq_exception": str(exc)})
121
122
  retry = False
122
123
  else:
123
124
  self._get_logger().error(
124
- 'Cannot publish to rabbitmq... giving up')
125
+ 'Cannot publish to rabbitmq... giving up',
126
+ extra={"rabbitmq_exception": str(exc)})
125
127
  break
126
128
 
127
129
  def _listen(self):
@@ -136,9 +138,10 @@ class KombuManager(PubSubManager): # pragma: no cover
136
138
  message.ack()
137
139
  yield message.payload
138
140
  retry_sleep = 1
139
- except (OSError, kombu.exceptions.KombuError):
141
+ except Exception as exc:
140
142
  self._get_logger().error(
141
- 'Cannot receive from rabbitmq... '
142
- 'retrying in {} secs'.format(retry_sleep))
143
+ 'Cannot receive from rabbotmq... retrying in '
144
+ f'{retry_sleep} secs',
145
+ extra={"rabbitmq_exception": str(exc)})
143
146
  time.sleep(retry_sleep)
144
147
  retry_sleep = min(retry_sleep * 2, 60)
socketio/redis_manager.py CHANGED
@@ -1,4 +1,3 @@
1
- import logging
2
1
  import time
3
2
  from urllib.parse import urlparse
4
3
 
@@ -18,8 +17,6 @@ except ImportError: # pragma: no cover
18
17
 
19
18
  from .pubsub_manager import PubSubManager
20
19
 
21
- logger = logging.getLogger('socketio')
22
-
23
20
 
24
21
  def parse_redis_sentinel_url(url):
25
22
  """Parse a Redis Sentinel URL with the format:
@@ -112,7 +109,7 @@ class RedisManager(PubSubManager):
112
109
  'Redis requires a monkey patched socket library to work '
113
110
  'with ' + self.server.async_mode)
114
111
 
115
- def _get_redis_module_and_error(self):
112
+ def _get_redis_module(self):
116
113
  parsed_url = urlparse(self.redis_url)
117
114
  scheme = parsed_url.scheme.split('+', 1)[0].lower()
118
115
  if scheme in ['redis', 'rediss']:
@@ -120,13 +117,13 @@ class RedisManager(PubSubManager):
120
117
  raise RuntimeError('Redis package is not installed '
121
118
  '(Run "pip install redis" '
122
119
  'in your virtualenv).')
123
- return redis, RedisError
120
+ return redis
124
121
  if scheme in ['valkey', 'valkeys']:
125
122
  if valkey is None or ValkeyError is None:
126
123
  raise RuntimeError('Valkey package is not installed '
127
124
  '(Run "pip install valkey" '
128
125
  'in your virtualenv).')
129
- return valkey, ValkeyError
126
+ return valkey
130
127
  if scheme == 'unix':
131
128
  if redis is None or RedisError is None:
132
129
  if valkey is None or ValkeyError is None:
@@ -135,14 +132,14 @@ class RedisManager(PubSubManager):
135
132
  'or "pip install valkey" '
136
133
  'in your virtualenv).')
137
134
  else:
138
- return valkey, ValkeyError
135
+ return valkey
139
136
  else:
140
- return redis, RedisError
137
+ return redis
141
138
  error_msg = f'Unsupported Redis URL scheme: {scheme}'
142
139
  raise ValueError(error_msg)
143
140
 
144
141
  def _redis_connect(self):
145
- module, _ = self._get_redis_module_and_error()
142
+ module = self._get_redis_module()
146
143
  parsed_url = urlparse(self.redis_url)
147
144
  if parsed_url.scheme in {"redis+sentinel", "valkey+sentinel"}:
148
145
  sentinels, service_name, connection_kwargs = \
@@ -158,28 +155,26 @@ class RedisManager(PubSubManager):
158
155
  self.connected = True
159
156
 
160
157
  def _publish(self, data): # pragma: no cover
161
- _, error = self._get_redis_module_and_error()
162
158
  for retries_left in range(1, -1, -1): # 2 attempts
163
159
  try:
164
160
  if not self.connected:
165
161
  self._redis_connect()
166
162
  return self.redis.publish(self.channel, self.json.dumps(data))
167
- except error as exc:
163
+ except Exception as exc:
168
164
  if retries_left > 0:
169
- logger.error(
165
+ self._get_logger().error(
170
166
  'Cannot publish to redis... retrying',
171
167
  extra={"redis_exception": str(exc)}
172
168
  )
173
169
  self.connected = False
174
170
  else:
175
- logger.error(
171
+ self._get_logger().error(
176
172
  'Cannot publish to redis... giving up',
177
173
  extra={"redis_exception": str(exc)}
178
174
  )
179
175
  break
180
176
 
181
177
  def _redis_listen_with_retries(self): # pragma: no cover
182
- _, error = self._get_redis_module_and_error()
183
178
  retry_sleep = 1
184
179
  subscribed = False
185
180
  while True:
@@ -189,10 +184,11 @@ class RedisManager(PubSubManager):
189
184
  self.pubsub.subscribe(self.channel)
190
185
  retry_sleep = 1
191
186
  yield from self.pubsub.listen()
192
- except error as exc:
193
- logger.error('Cannot receive from redis... '
194
- f'retrying in {retry_sleep} secs',
195
- extra={"redis_exception": str(exc)})
187
+ except Exception as exc:
188
+ self._get_logger().error(
189
+ 'Cannot receive from redis... '
190
+ f'retrying in {retry_sleep} secs',
191
+ extra={"redis_exception": str(exc)})
196
192
  subscribed = False
197
193
  time.sleep(retry_sleep)
198
194
  retry_sleep *= 2
socketio/server.py CHANGED
@@ -402,6 +402,8 @@ class Server(base_server.BaseServer):
402
402
  if delete_it:
403
403
  self.logger.info('Disconnecting %s [%s]', sid, namespace)
404
404
  eio_sid = self.manager.pre_disconnect(sid, namespace=namespace)
405
+ if eio_sid in self._binary_packet:
406
+ del self._binary_packet[eio_sid]
405
407
  self._send_packet(eio_sid, self.packet_class(
406
408
  packet.DISCONNECT, namespace=namespace))
407
409
  self._trigger_event('disconnect', namespace, sid,
@@ -663,6 +665,9 @@ class Server(base_server.BaseServer):
663
665
  self._handle_ack(eio_sid, pkt.namespace, pkt.id, pkt.data)
664
666
  elif pkt.packet_type == packet.BINARY_EVENT or \
665
667
  pkt.packet_type == packet.BINARY_ACK:
668
+ if not self.manager.sid_from_eio_sid(eio_sid,
669
+ pkt.namespace or '/'):
670
+ raise ValueError('Unexpected binary packet')
666
671
  self._binary_packet[eio_sid] = pkt
667
672
  elif pkt.packet_type == packet.CONNECT_ERROR:
668
673
  raise ValueError('Unexpected CONNECT_ERROR packet.')