Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-Flask-SocketIO for
openSUSE:Factory checked in at 2023-06-22 23:26:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Flask-SocketIO (Old)
and /work/SRC/openSUSE:Factory/.python-Flask-SocketIO.new.15902 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Flask-SocketIO"
Thu Jun 22 23:26:07 2023 rev:3 rq:1094493 version:5.3.4
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-Flask-SocketIO/python-Flask-SocketIO.changes
2021-10-27 22:21:45.147215476 +0200
+++
/work/SRC/openSUSE:Factory/.python-Flask-SocketIO.new.15902/python-Flask-SocketIO.changes
2023-06-22 23:26:31.181981912 +0200
@@ -1,0 +2,11 @@
+Wed Jun 21 21:36:05 UTC 2023 - Matej Cepl <[email protected]>
+
+- Clean up SPEC file, make rpmlint happy.
+
+-------------------------------------------------------------------
+Wed Jun 21 19:56:26 UTC 2023 - Axel Braun <[email protected]>
+
+- update to version 5.3.4
+ * For a full changelog see
https://github.com/miguelgrinberg/Flask-SocketIO/blob/main/CHANGES.md
+
+-------------------------------------------------------------------
Old:
----
Flask-SocketIO-5.1.1.tar.gz
New:
----
Flask-SocketIO-5.3.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-Flask-SocketIO.spec ++++++
--- /var/tmp/diff_new_pack.p8vss1/_old 2023-06-22 23:26:31.825985197 +0200
+++ /var/tmp/diff_new_pack.p8vss1/_new 2023-06-22 23:26:31.829985217 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-Flask-SocketIO
#
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,24 +16,24 @@
#
-%{?!python_module:%define python_module() python3-%{**}}
%define skip_python2 1
Name: python-Flask-SocketIO
-Version: 5.1.1
+Version: 5.3.4
Release: 0
-License: MIT
Summary: SocketIO integration for Flask applications
-URL: http://github.com/miguelgrinberg/Flask-SocketIO/
+License: MIT
Group: Development/Languages/Python
+URL: https://github.com/miguelgrinberg/Flask-SocketIO/
Source:
https://files.pythonhosted.org/packages/source/F/Flask-SocketIO/Flask-SocketIO-%{version}.tar.gz
Source1:
https://raw.githubusercontent.com/miguelgrinberg/Flask-SocketIO/v%{version}/test_socketio.py
BuildRequires: %{python_module Flask >= 0.9}
+BuildRequires: %{python_module pip}
BuildRequires: %{python_module python-socketio >= 5.0.2}
-BuildRequires: %{python_module setuptools}
+BuildRequires: %{python_module redis}
+BuildRequires: %{python_module wheel}
BuildRequires: fdupes
Requires: python-Flask >= 0.9
Requires: python-python-socketio >= 5.0.2
-
BuildArch: noarch
%python_subpackages
@@ -42,13 +42,13 @@
%prep
%setup -q -n Flask-SocketIO-%{version}
-cp %{S:1} .
+cp %{SOURCE1} .
%build
-%python_build
+%pyproject_wheel
%install
-%python_install
+%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%check
@@ -57,6 +57,7 @@
%files %{python_files}
%doc README.md
%license LICENSE
-%{python_sitelib}/*
+%{python_sitelib}/flask_socketio
+%{python_sitelib}/Flask_SocketIO-%{version}*-info
%changelog
++++++ Flask-SocketIO-5.1.1.tar.gz -> Flask-SocketIO-5.3.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-SocketIO-5.1.1/PKG-INFO
new/Flask-SocketIO-5.3.4/PKG-INFO
--- old/Flask-SocketIO-5.1.1/PKG-INFO 2021-08-02 01:17:34.347939500 +0200
+++ new/Flask-SocketIO-5.3.4/PKG-INFO 2023-05-03 12:34:08.560571200 +0200
@@ -1,13 +1,11 @@
Metadata-Version: 2.1
Name: Flask-SocketIO
-Version: 5.1.1
+Version: 5.3.4
Summary: Socket.IO integration for Flask applications
Home-page: https://github.com/miguelgrinberg/flask-socketio
Author: Miguel Grinberg
Author-email: [email protected]
-License: UNKNOWN
Project-URL: Bug Tracker,
https://github.com/miguelgrinberg/flask-socketio/issues
-Platform: UNKNOWN
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
@@ -73,5 +71,3 @@
- [Change
Log](https://github.com/miguelgrinberg/Flask-SocketIO/blob/main/CHANGES.md)
- Questions? See the
[questions](https://stackoverflow.com/questions/tagged/flask-socketio) others
have asked on Stack Overflow, or
[ask](https://stackoverflow.com/questions/ask?tags=python+flask-socketio+python-socketio)
your own question.
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-SocketIO-5.1.1/setup.cfg
new/Flask-SocketIO-5.3.4/setup.cfg
--- old/Flask-SocketIO-5.1.1/setup.cfg 2021-08-02 01:17:34.348511000 +0200
+++ new/Flask-SocketIO-5.3.4/setup.cfg 2023-05-03 12:34:08.561552300 +0200
@@ -1,6 +1,6 @@
[metadata]
name = Flask-SocketIO
-version = 5.1.1
+version = 5.3.4
author = Miguel Grinberg
author_email = [email protected]
description = Socket.IO integration for Flask applications
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-SocketIO-5.1.1/src/Flask_SocketIO.egg-info/PKG-INFO
new/Flask-SocketIO-5.3.4/src/Flask_SocketIO.egg-info/PKG-INFO
--- old/Flask-SocketIO-5.1.1/src/Flask_SocketIO.egg-info/PKG-INFO
2021-08-02 01:17:34.000000000 +0200
+++ new/Flask-SocketIO-5.3.4/src/Flask_SocketIO.egg-info/PKG-INFO
2023-05-03 12:34:08.000000000 +0200
@@ -1,13 +1,11 @@
Metadata-Version: 2.1
Name: Flask-SocketIO
-Version: 5.1.1
+Version: 5.3.4
Summary: Socket.IO integration for Flask applications
Home-page: https://github.com/miguelgrinberg/flask-socketio
Author: Miguel Grinberg
Author-email: [email protected]
-License: UNKNOWN
Project-URL: Bug Tracker,
https://github.com/miguelgrinberg/flask-socketio/issues
-Platform: UNKNOWN
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
@@ -73,5 +71,3 @@
- [Change
Log](https://github.com/miguelgrinberg/Flask-SocketIO/blob/main/CHANGES.md)
- Questions? See the
[questions](https://stackoverflow.com/questions/tagged/flask-socketio) others
have asked on Stack Overflow, or
[ask](https://stackoverflow.com/questions/ask?tags=python+flask-socketio+python-socketio)
your own question.
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Flask-SocketIO-5.1.1/src/flask_socketio/__init__.py
new/Flask-SocketIO-5.3.4/src/flask_socketio/__init__.py
--- old/Flask-SocketIO-5.1.1/src/flask_socketio/__init__.py 2021-07-18
18:30:40.000000000 +0200
+++ new/Flask-SocketIO-5.3.4/src/flask_socketio/__init__.py 2023-03-21
20:59:26.000000000 +0100
@@ -16,7 +16,7 @@
sys.exit(1)
import flask
-from flask import _request_ctx_stack, has_request_context, json as flask_json
+from flask import has_request_context, json as flask_json
from flask.sessions import SessionMixin
import socketio
from socketio.exceptions import ConnectionRefusedError # noqa: F401
@@ -197,8 +197,8 @@
self.manage_session = self.server_options.pop('manage_session',
self.manage_session)
- if 'client_manager' not in self.server_options:
- url = self.server_options.pop('message_queue', None)
+ if 'client_manager' not in kwargs:
+ url = self.server_options.get('message_queue', None)
channel = self.server_options.pop('channel', 'flask-socketio')
write_only = app is None
if url:
@@ -248,7 +248,7 @@
self.server.register_namespace(namespace_handler)
if app is not None:
- # here we attach the SocketIO middlware to the SocketIO object so
+ # here we attach the SocketIO middleware to the SocketIO object so
# it can be referenced later if debug middleware needs to be
# inserted
self.sockio_mw = _SocketIOMiddleware(self.server, app,
@@ -416,9 +416,9 @@
:param args: A dictionary with the JSON data to send as payload.
:param namespace: The namespace under which the message is to be sent.
Defaults to the global namespace.
- :param to: Send the message to all the users in the given room. If
- this parameter is not included, the event is sent to all
- connected users.
+ :param to: Send the message to all the users in the given room, or to
+ the user with the given session ID. If this parameter is not
+ included, the event is sent to all connected users.
:param include_self: ``True`` to include the sender when broadcasting
or addressing a room, or ``False`` to send to
everyone but the sender.
@@ -434,7 +434,7 @@
only be used when addressing an individual client.
"""
namespace = kwargs.pop('namespace', '/')
- to = kwargs.pop('to', kwargs.pop('room', None))
+ to = kwargs.pop('to', None) or kwargs.pop('room', None)
include_self = kwargs.pop('include_self', True)
skip_sid = kwargs.pop('skip_sid', None)
if not include_self and not skip_sid:
@@ -443,13 +443,15 @@
if callback:
# wrap the callback so that it sets app app and request contexts
sid = None
+ original_callback = callback
+ original_namespace = namespace
if has_request_context():
sid = getattr(flask.request, 'sid', None)
- original_callback = callback
+ original_namespace = getattr(flask.request, 'namespace', None)
def _callback_wrapper(*args):
- return self._handle_event(original_callback, None, namespace,
- sid, *args)
+ return self._handle_event(original_callback, None,
+ original_namespace, sid, *args)
if sid:
# the callback wrapper above will install a request context
@@ -460,6 +462,41 @@
self.server.emit(event, *args, namespace=namespace, to=to,
skip_sid=skip_sid, callback=callback, **kwargs)
+ def call(self, event, *args, **kwargs): # pragma: no cover
+ """Emit a SocketIO event and wait for the response.
+
+ This method issues an emit with a callback and waits for the callback
+ to be invoked by the client before returning. If the callback isnât
+ invoked before the timeout, then a TimeoutError exception is raised. If
+ the Socket.IO connection drops during the wait, this method still waits
+ until the specified timeout. Example::
+
+ def get_status(client, data):
+ status = call('status', {'data': data}, to=client)
+
+ :param event: The name of the user event to emit.
+ :param args: A dictionary with the JSON data to send as payload.
+ :param namespace: The namespace under which the message is to be sent.
+ Defaults to the global namespace.
+ :param to: The session ID of the recipient client.
+ :param timeout: The waiting timeout. If the timeout is reached before
+ the client acknowledges the event, then a
+ ``TimeoutError`` exception is raised. The default is 60
+ seconds.
+ :param ignore_queue: Only used when a message queue is configured. If
+ set to ``True``, the event is emitted to the
+ client directly, without going through the queue.
+ This is more efficient, but only works when a
+ single server process is used, or when there is a
+ single addressee. It is recommended to always
+ leave this parameter with its default value of
+ ``False``.
+ """
+ namespace = kwargs.pop('namespace', '/')
+ to = kwargs.pop('to', None) or kwargs.pop('room', None)
+ return self.server.call(event, *args, namespace=namespace, to=to,
+ **kwargs)
+
def send(self, data, json=False, namespace=None, to=None,
callback=None, include_self=True, skip_sid=None, **kwargs):
"""Send a server-generated SocketIO message.
@@ -475,9 +512,9 @@
otherwise.
:param namespace: The namespace under which the message is to be sent.
Defaults to the global namespace.
- :param to: Send the message only to the users in the given room. If
- this parameter is not included, the message is sent to all
- connected users.
+ :param to: Send the message to all the users in the given room, or to
+ the user with the given session ID. If this parameter is not
+ included, the event is sent to all connected users.
:param include_self: ``True`` to include the sender when broadcasting
or addressing a room, or ``False`` to send to
everyone but the sender.
@@ -536,6 +573,10 @@
Defaults to ``True`` in debug mode, ``False``
in normal mode. Unused when the threading async
mode is used.
+ :param allow_unsafe_werkzeug: Set to ``True`` to allow the use of the
+ Werkzeug web server in a production
+ setting. Default is ``False``. Set to
+ ``True`` at your own risk.
:param kwargs: Additional web server options. The web server options
are specific to the server used in each of the supported
async modes. Note that options provided here will
@@ -593,6 +634,20 @@
from werkzeug._internal import _log
_log('warning', 'WebSocket transport not available. Install '
'simple-websocket for improved performance.')
+ allow_unsafe_werkzeug = kwargs.pop('allow_unsafe_werkzeug',
+ False)
+ if not sys.stdin or not sys.stdin.isatty(): # pragma: no cover
+ if not allow_unsafe_werkzeug:
+ raise RuntimeError('The Werkzeug web server is not '
+ 'designed to run in production. Pass '
+ 'allow_unsafe_werkzeug=True to the '
+ 'run() method to disable this error.')
+ else:
+ from werkzeug._internal import _log
+ _log('warning', ('Werkzeug appears to be used in a '
+ 'production deployment. Consider '
+ 'switching to a production web server '
+ 'instead.'))
app.run(host=host, port=port, threaded=True,
use_reloader=use_reloader, **reloader_options, **kwargs)
elif self.server.eio.async_mode == 'eventlet':
@@ -690,9 +745,9 @@
:param args: arguments to pass to the function.
:param kwargs: keyword arguments to pass to the function.
- This function returns an object compatible with the `Thread` class in
- the Python standard library. The `start()` method on this object is
- already called by this function.
+ This function returns an object that represents the background task,
+ on which the ``join()`` method can be invoked to wait for the task to
+ complete.
"""
return self.server.start_background_task(target, *args, **kwargs)
@@ -744,6 +799,14 @@
if 'saved_session' not in environ:
environ['saved_session'] = _ManagedSession(flask.session)
session_obj = environ['saved_session']
+ if hasattr(flask, 'globals') and \
+ hasattr(flask.globals, 'request_ctx'):
+ # update session for Flask >= 2.2
+ ctx = flask.globals.request_ctx._get_current_object()
+ else: # pragma: no cover
+ # update session for Flask < 2.2
+ ctx = flask._request_ctx_stack.top
+ ctx.session = session_obj
else:
# let Flask handle the user session
# for cookie based sessions, this effectively freezes the
@@ -751,7 +814,6 @@
# for server-side sessions, this allows HTTP and Socket.IO to
# share the session, with both having read/write access to it
session_obj = flask.session._get_current_object()
- _request_ctx_stack.top.session = session_obj
flask.request.sid = sid
flask.request.namespace = namespace
flask.request.event = {'message': message, 'args': args}
@@ -764,6 +826,8 @@
ret = handler()
else:
ret = handler(*args)
+ except ConnectionRefusedError:
+ raise # let this error bubble up to python-socketio
except:
err_handler = self.exception_handlers.get(
namespace, self.default_exception_handler)
@@ -802,9 +866,10 @@
acknowledgement.
:param broadcast: ``True`` to send the message to all clients, or ``False``
to only reply to the sender of the originating event.
- :param to: Send the message to all the users in the given room. If this
- argument is not set and ``broadcast`` is ``False``, then the
- message is sent only to the originating user.
+ :param to: Send the message to all the users in the given room, or to the
+ user with the given session ID. If this argument is not set and
+ ``broadcast`` is ``False``, then the message is sent only to the
+ originating user.
:param include_self: ``True`` to include the sender when broadcasting or
addressing a room, or ``False`` to send to everyone
but the sender.
@@ -827,7 +892,7 @@
namespace = flask.request.namespace
callback = kwargs.get('callback')
broadcast = kwargs.get('broadcast')
- to = kwargs.pop('to', kwargs.pop('room', None))
+ to = kwargs.pop('to', None) or kwargs.pop('room', None)
if to is None and not broadcast:
to = flask.request.sid
include_self = kwargs.get('include_self', True)
@@ -840,6 +905,52 @@
callback=callback, ignore_queue=ignore_queue)
+def call(event, *args, **kwargs): # pragma: no cover
+ """Emit a SocketIO event and wait for the response.
+
+ This function issues an emit with a callback and waits for the callback to
+ be invoked by the client before returning. If the callback isnât invoked
+ before the timeout, then a TimeoutError exception is raised. If the
+ Socket.IO connection drops during the wait, this method still waits until
+ the specified timeout. Example::
+
+ def get_status(client, data):
+ status = call('status', {'data': data}, to=client)
+
+ :param event: The name of the user event to emit.
+ :param args: A dictionary with the JSON data to send as payload.
+ :param namespace: The namespace under which the message is to be sent.
+ Defaults to the namespace used by the originating event.
+ A ``'/'`` can be used to explicitly specify the global
+ namespace.
+ :param to: The session ID of the recipient client. If this argument is not
+ given, the event is sent to the originating client.
+ :param timeout: The waiting timeout. If the timeout is reached before the
+ client acknowledges the event, then a ``TimeoutError``
+ exception is raised. The default is 60 seconds.
+ :param ignore_queue: Only used when a message queue is configured. If
+ set to ``True``, the event is emitted to the
+ client directly, without going through the queue.
+ This is more efficient, but only works when a
+ single server process is used, or when there is a
+ single addressee. It is recommended to always leave
+ this parameter with its default value of ``False``.
+ """
+ if 'namespace' in kwargs:
+ namespace = kwargs['namespace']
+ else:
+ namespace = flask.request.namespace
+ to = kwargs.pop('to', None) or kwargs.pop('room', None)
+ if to is None:
+ to = flask.request.sid
+ timeout = kwargs.get('timeout', 60)
+ ignore_queue = kwargs.get('ignore_queue', False)
+
+ socketio = flask.current_app.extensions['socketio']
+ return socketio.call(event, *args, namespace=namespace, to=to,
+ ignore_queue=ignore_queue, timeout=timeout)
+
+
def send(message, **kwargs):
"""Send a SocketIO message.
@@ -859,9 +970,10 @@
:param broadcast: ``True`` to send the message to all connected clients, or
``False`` to only reply to the sender of the originating
event.
- :param to: Send the message to all the users in the given room. If this
- argument is not set and ``broadcast`` is ``False``, then the
- message is sent only to the originating user.
+ :param to: Send the message to all the users in the given room, or to the
+ user with the given session ID. If this argument is not set and
+ ``broadcast`` is ``False``, then the message is sent only to the
+ originating user.
:param include_self: ``True`` to include the sender when broadcasting or
addressing a room, or ``False`` to send to everyone
but the sender.
@@ -885,7 +997,7 @@
namespace = flask.request.namespace
callback = kwargs.get('callback')
broadcast = kwargs.get('broadcast')
- to = kwargs.pop('to', kwargs.pop('room', None))
+ to = kwargs.pop('to', None) or kwargs.pop('room', None)
if to is None and not broadcast:
to = flask.request.sid
include_self = kwargs.get('include_self', True)
@@ -910,7 +1022,7 @@
username = session['username']
room = data['room']
join_room(room)
- send(username + ' has entered the room.', room=room)
+ send(username + ' has entered the room.', to=room)
:param room: The name of the room to join.
:param sid: The session id of the client. If not provided, the client is
@@ -935,7 +1047,7 @@
username = session['username']
room = data['room']
leave_room(room)
- send(username + ' has left the room.', room=room)
+ send(username + ' has left the room.', to=room)
:param room: The name of the room to leave.
:param sid: The session id of the client. If not provided, the client is
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Flask-SocketIO-5.1.1/src/flask_socketio/test_client.py
new/Flask-SocketIO-5.3.4/src/flask_socketio/test_client.py
--- old/Flask-SocketIO-5.1.1/src/flask_socketio/test_client.py 2021-06-13
17:46:50.000000000 +0200
+++ new/Flask-SocketIO-5.3.4/src/flask_socketio/test_client.py 2023-05-03
12:28:48.000000000 +0200
@@ -24,8 +24,7 @@
cookies set in HTTP routes accessible from
Socket.IO events.
"""
- queue = {}
- acks = {}
+ clients = {}
def __init__(self, app, socketio, namespace=None, query_string=None,
headers=None, auth=None, flask_test_client=None):
@@ -38,35 +37,37 @@
pkt = packet.Packet(encoded_packet=epkt[0])
for att in epkt[1:]:
pkt.add_attachment(att)
+ client = self.clients.get(eio_sid)
+ if not client:
+ return
if pkt.packet_type == packet.EVENT or \
pkt.packet_type == packet.BINARY_EVENT:
- if eio_sid not in self.queue:
- self.queue[eio_sid] = []
if pkt.data[0] == 'message' or pkt.data[0] == 'json':
- self.queue[eio_sid].append({
+ client.queue.append({
'name': pkt.data[0],
'args': pkt.data[1],
'namespace': pkt.namespace or '/'})
else:
- self.queue[eio_sid].append({
+ client.queue.append({
'name': pkt.data[0],
'args': pkt.data[1:],
'namespace': pkt.namespace or '/'})
elif pkt.packet_type == packet.ACK or \
pkt.packet_type == packet.BINARY_ACK:
- self.acks[eio_sid] = {'args': pkt.data,
- 'namespace': pkt.namespace or '/'}
+ client.acks = {'args': pkt.data,
+ 'namespace': pkt.namespace or '/'}
elif pkt.packet_type in [packet.DISCONNECT, packet.CONNECT_ERROR]:
- self.connected[pkt.namespace or '/'] = False
+ client.connected[pkt.namespace or '/'] = False
self.app = app
self.flask_test_client = flask_test_client
self.eio_sid = uuid.uuid4().hex
- self.acks[self.eio_sid] = None
- self.queue[self.eio_sid] = []
+ self.clients[self.eio_sid] = self
self.callback_counter = 0
self.socketio = socketio
self.connected = {}
+ self.queue = []
+ self.acks = None
socketio.server._send_packet = _mock_send_packet
socketio.server.environ[self.eio_sid] = {}
socketio.server.async_handlers = False # easier to test when
@@ -113,12 +114,15 @@
environ['flask.app'] = self.app
if self.flask_test_client:
# inject cookies from Flask
- self.flask_test_client.cookie_jar.inject_wsgi(environ)
+ if hasattr(self.flask_test_client, '_add_cookies_to_wsgi'):
+ # flask >= 2.3
+ self.flask_test_client._add_cookies_to_wsgi(environ)
+ else: # pragma: no cover
+ # flask < 2.3
+ self.flask_test_client.cookie_jar.inject_wsgi(environ)
self.socketio.server._handle_eio_connect(self.eio_sid, environ)
pkt = packet.Packet(packet.CONNECT, auth, namespace=namespace)
- with self.app.app_context():
- self.socketio.server._handle_eio_message(self.eio_sid,
- pkt.encode())
+ self.socketio.server._handle_eio_message(self.eio_sid, pkt.encode())
sid = self.socketio.server.manager.sid_from_eio_sid(self.eio_sid,
namespace)
if sid:
@@ -133,9 +137,7 @@
if not self.is_connected(namespace):
raise RuntimeError('not connected')
pkt = packet.Packet(packet.DISCONNECT, namespace=namespace)
- with self.app.app_context():
- self.socketio.server._handle_eio_message(self.eio_sid,
- pkt.encode())
+ self.socketio.server._handle_eio_message(self.eio_sid, pkt.encode())
del self.connected[namespace or '/']
def emit(self, event, *args, **kwargs):
@@ -163,17 +165,15 @@
id = self.callback_counter
pkt = packet.Packet(packet.EVENT, data=[event] + list(args),
namespace=namespace, id=id)
- with self.app.app_context():
- encoded_pkt = pkt.encode()
- if isinstance(encoded_pkt, list):
- for epkt in encoded_pkt:
- self.socketio.server._handle_eio_message(self.eio_sid,
- epkt)
- else:
- self.socketio.server._handle_eio_message(self.eio_sid,
- encoded_pkt)
- ack = self.acks.pop(self.eio_sid, None)
- if ack is not None:
+ encoded_pkt = pkt.encode()
+ if isinstance(encoded_pkt, list):
+ for epkt in encoded_pkt:
+ self.socketio.server._handle_eio_message(self.eio_sid, epkt)
+ else:
+ self.socketio.server._handle_eio_message(self.eio_sid, encoded_pkt)
+ if self.acks is not None:
+ ack = self.acks
+ self.acks = None
return ack['args'][0] if len(ack['args']) == 1 \
else ack['args']
@@ -213,8 +213,6 @@
if not self.is_connected(namespace):
raise RuntimeError('not connected')
namespace = namespace or '/'
- r = [pkt for pkt in self.queue[self.eio_sid]
- if pkt['namespace'] == namespace]
- self.queue[self.eio_sid] = [
- pkt for pkt in self.queue[self.eio_sid] if pkt not in r]
+ r = [pkt for pkt in self.queue if pkt['namespace'] == namespace]
+ self.queue = [pkt for pkt in self.queue if pkt not in r]
return r
++++++ test_socketio.py ++++++
--- /var/tmp/diff_new_pack.p8vss1/_old 2023-06-22 23:26:32.021986196 +0200
+++ /var/tmp/diff_new_pack.p8vss1/_new 2023-06-22 23:26:32.021986196 +0200
@@ -3,7 +3,7 @@
from flask import Flask, session, request, json as flask_json
from flask_socketio import SocketIO, send, emit, join_room, leave_room, \
- Namespace, disconnect
+ Namespace, disconnect, ConnectionRefusedError
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
@@ -16,11 +16,12 @@
if auth != {'foo': 'bar'}: # pragma: no cover
return False
if request.args.get('fail'):
- return False
+ raise ConnectionRefusedError('failed!')
send('connected')
send(json.dumps(request.args.to_dict(flat=False)))
send(json.dumps({h: request.headers[h] for h in request.headers.keys()
if h not in ['Host', 'Content-Type', 'Content-Length']}))
+ emit('dummy', to='nobody')
@socketio.on('disconnect')
@@ -47,7 +48,12 @@
def message(message):
send(message)
if message == 'test session':
- session['a'] = 'b'
+ if not socketio.manage_session and 'a' in session:
+ raise RuntimeError('session is being stored')
+ if 'a' not in session:
+ session['a'] = 'b'
+ else:
+ session['a'] = 'c'
if message not in "test noackargs":
return message
@@ -345,6 +351,25 @@
client.disconnect('/test')
self.assertEqual(disconnected, '/test')
+ def test_message_queue_options(self):
+ app = Flask(__name__)
+ socketio = SocketIO(app, message_queue='redis://')
+ self.assertFalse(socketio.server_options['client_manager'].write_only)
+
+ app = Flask(__name__)
+ socketio = SocketIO(app)
+ socketio.init_app(app, message_queue='redis://')
+ self.assertFalse(socketio.server_options['client_manager'].write_only)
+
+ app = Flask(__name__)
+ socketio = SocketIO(message_queue='redis://')
+ self.assertTrue(socketio.server_options['client_manager'].write_only)
+
+ app = Flask(__name__)
+ socketio = SocketIO()
+ socketio.init_app(None, message_queue='redis://')
+ self.assertTrue(socketio.server_options['client_manager'].write_only)
+
def test_send(self):
client = socketio.test_client(app, auth={'foo': 'bar'})
client.get_received()
@@ -454,7 +479,7 @@
self.assertEqual(received[0]['args'][0]['a'], 'b')
self.assertEqual(len(client3.get_received()), 0)
- def test_session(self):
+ def test_managed_session(self):
flask_client = app.test_client()
flask_client.get('/session')
client = socketio.test_client(app, flask_test_client=flask_client,
@@ -468,6 +493,21 @@
self.assertEqual(
socketio.server.environ[client.eio_sid]['saved_session'],
{'a': 'b', 'foo': 'bar'})
+ client.send('test session')
+ self.assertEqual(
+ socketio.server.environ[client.eio_sid]['saved_session'],
+ {'a': 'c', 'foo': 'bar'})
+
+ def test_unmanaged_session(self):
+ socketio.manage_session = False
+ flask_client = app.test_client()
+ flask_client.get('/session')
+ client = socketio.test_client(app, flask_test_client=flask_client,
+ auth={'foo': 'bar'})
+ client.get_received()
+ client.send('test session')
+ client.send('test session')
+ socketio.manage_session = True
def test_room(self):
client1 = socketio.test_client(app, auth={'foo': 'bar'})
@@ -647,11 +687,18 @@
def test_server_disconnected(self):
client = socketio.test_client(app, namespace='/ns')
+ client2 = socketio.test_client(app, namespace='/ns')
client.get_received('/ns')
+ client2.get_received('/ns')
client.emit('exit', {}, namespace='/ns')
self.assertFalse(client.is_connected('/ns'))
+ self.assertTrue(client2.is_connected('/ns'))
with self.assertRaises(RuntimeError):
client.emit('hello', {}, namespace='/ns')
+ client2.emit('exit', {}, namespace='/ns')
+ self.assertFalse(client2.is_connected('/ns'))
+ with self.assertRaises(RuntimeError):
+ client2.emit('hello', {}, namespace='/ns')
def test_emit_class_based(self):
client = socketio.test_client(app, namespace='/ns')