python-engineio 4.12.3__tar.gz → 4.13.1__tar.gz
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.
- {python_engineio-4.12.3/src/python_engineio.egg-info → python_engineio-4.13.1}/PKG-INFO +6 -3
- python_engineio-4.13.1/docs/api.rst +14 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/docs/client.rst +7 -3
- {python_engineio-4.12.3 → python_engineio-4.13.1}/docs/conf.py +2 -11
- {python_engineio-4.12.3 → python_engineio-4.13.1}/docs/index.rst +1 -1
- {python_engineio-4.12.3 → python_engineio-4.13.1}/docs/server.rst +7 -3
- {python_engineio-4.12.3 → python_engineio-4.13.1}/pyproject.toml +12 -4
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_client.py +11 -8
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/aiohttp.py +9 -16
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/asgi.py +3 -3
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/tornado.py +2 -1
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_server.py +8 -6
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/client.py +9 -5
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/server.py +4 -3
- {python_engineio-4.12.3 → python_engineio-4.13.1/src/python_engineio.egg-info}/PKG-INFO +6 -3
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/python_engineio.egg-info/requires.txt +5 -1
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/test_aiohttp.py +19 -6
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/test_client.py +17 -1
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tox.ini +3 -3
- python_engineio-4.12.3/docs/api.rst +0 -33
- {python_engineio-4.12.3 → python_engineio-4.13.1}/LICENSE +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/MANIFEST.in +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/README.md +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/docs/Makefile +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/docs/_static/README.md +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/docs/intro.rst +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/docs/make.bat +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/setup.cfg +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/__init__.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/__init__.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/_websocket_wsgi.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/eventlet.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/gevent.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/gevent_uwsgi.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/sanic.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/threading.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_socket.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/base_client.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/base_server.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/base_socket.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/exceptions.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/json.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/middleware.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/packet.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/payload.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/socket.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/static_files.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/python_engineio.egg-info/SOURCES.txt +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/python_engineio.egg-info/dependency_links.txt +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/python_engineio.egg-info/not-zip-safe +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/src/python_engineio.egg-info/top_level.txt +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/__init__.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/__init__.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/index.html +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/test_asgi.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/test_sanic.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/test_server.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/test_socket.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/async/test_tornado.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/common/__init__.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/common/index.html +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/common/test_client.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/common/test_middleware.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/common/test_packet.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/common/test_payload.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/common/test_server.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/common/test_socket.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/performance/README.md +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/performance/binary_b64_packet.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/performance/binary_packet.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/performance/json_packet.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/performance/payload.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/performance/run.sh +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/performance/server_receive.py +0 -0
- {python_engineio-4.12.3 → python_engineio-4.13.1}/tests/performance/text_packet.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-engineio
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.13.1
|
|
4
4
|
Summary: Engine.IO server and client for Python
|
|
5
5
|
Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -10,7 +10,7 @@ Classifier: Environment :: Web Environment
|
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
|
-
Requires-Python: >=3.
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
Requires-Dist: simple-websocket>=0.10.0
|
|
@@ -18,9 +18,12 @@ Provides-Extra: client
|
|
|
18
18
|
Requires-Dist: requests>=2.21.0; extra == "client"
|
|
19
19
|
Requires-Dist: websocket-client>=0.54.0; extra == "client"
|
|
20
20
|
Provides-Extra: asyncio-client
|
|
21
|
-
Requires-Dist: aiohttp>=3.
|
|
21
|
+
Requires-Dist: aiohttp>=3.11; extra == "asyncio-client"
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: tox; extra == "dev"
|
|
22
24
|
Provides-Extra: docs
|
|
23
25
|
Requires-Dist: sphinx; extra == "docs"
|
|
26
|
+
Requires-Dist: furo; extra == "docs"
|
|
24
27
|
Dynamic: license-file
|
|
25
28
|
|
|
26
29
|
python-engineio
|
|
@@ -199,9 +199,13 @@ terminal::
|
|
|
199
199
|
# asyncio
|
|
200
200
|
eio = engineio.AsyncClient(logger=True)
|
|
201
201
|
|
|
202
|
-
The ``logger`` argument
|
|
203
|
-
|
|
204
|
-
|
|
202
|
+
The ``logger`` argument controls logging behavior:
|
|
203
|
+
|
|
204
|
+
* ``True``: Enables log output to ``stderr`` at the ``INFO`` level.
|
|
205
|
+
* ``False``: Enables log output to ``stderr`` at the ``ERROR`` level. This is
|
|
206
|
+
the default.
|
|
207
|
+
* A ``logging.Logger`` instance: Uses the provided logger without additional
|
|
208
|
+
configuration.
|
|
205
209
|
|
|
206
210
|
Logging can help identify the cause of connection problems, unexpected
|
|
207
211
|
disconnections and other issues.
|
|
@@ -67,29 +67,20 @@ language = None
|
|
|
67
67
|
# This pattern also affects html_static_path and html_extra_path.
|
|
68
68
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|
69
69
|
|
|
70
|
-
# The name of the Pygments (syntax highlighting) style to use.
|
|
71
|
-
pygments_style = None
|
|
72
|
-
|
|
73
70
|
|
|
74
71
|
# -- Options for HTML output -------------------------------------------------
|
|
75
72
|
|
|
76
73
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
77
74
|
# a list of builtin themes.
|
|
78
75
|
#
|
|
79
|
-
html_theme = '
|
|
76
|
+
html_theme = 'furo'
|
|
77
|
+
html_title = 'python-engineio'
|
|
80
78
|
|
|
81
79
|
# Theme options are theme-specific and customize the look and feel of a theme
|
|
82
80
|
# further. For a list of options available for each theme, see the
|
|
83
81
|
# documentation.
|
|
84
82
|
#
|
|
85
83
|
html_theme_options = {
|
|
86
|
-
'github_user': 'miguelgrinberg',
|
|
87
|
-
'github_repo': 'python-engineio',
|
|
88
|
-
'github_banner': True,
|
|
89
|
-
'github_button': True,
|
|
90
|
-
'github_type': 'star',
|
|
91
|
-
'fixed_sidebar': True,
|
|
92
|
-
|
|
93
84
|
}
|
|
94
85
|
|
|
95
86
|
# Add any paths that contain custom static files (such as style sheets) here,
|
|
@@ -350,9 +350,13 @@ terminal::
|
|
|
350
350
|
# asyncio
|
|
351
351
|
eio = engineio.AsyncServer(logger=True)
|
|
352
352
|
|
|
353
|
-
The ``logger`` argument
|
|
354
|
-
|
|
355
|
-
|
|
353
|
+
The ``logger`` argument controls logging behavior:
|
|
354
|
+
|
|
355
|
+
* ``True``: Enables log output to ``stderr`` at the ``INFO`` level.
|
|
356
|
+
* ``False``: Enables log output to ``stderr`` at the ``ERROR`` level. This is
|
|
357
|
+
the default.
|
|
358
|
+
* A ``logging.Logger`` instance: Uses the provided logger without additional
|
|
359
|
+
configuration.
|
|
356
360
|
|
|
357
361
|
Logging can help identify the cause of connection problems, 400 responses,
|
|
358
362
|
bad performance and other issues.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-engineio"
|
|
3
|
-
version = "4.
|
|
3
|
+
version = "4.13.1"
|
|
4
4
|
license = {text = "MIT"}
|
|
5
5
|
authors = [{name = "Miguel Grinberg", email = "miguel.grinberg@gmail.com"}]
|
|
6
6
|
description = "Engine.IO server and client for Python"
|
|
@@ -10,7 +10,7 @@ classifiers = [
|
|
|
10
10
|
"Programming Language :: Python :: 3",
|
|
11
11
|
"Operating System :: OS Independent",
|
|
12
12
|
]
|
|
13
|
-
requires-python = ">=3.
|
|
13
|
+
requires-python = ">=3.8"
|
|
14
14
|
dependencies = ["simple-websocket >= 0.10.0"]
|
|
15
15
|
|
|
16
16
|
[project.readme]
|
|
@@ -26,8 +26,16 @@ client = [
|
|
|
26
26
|
"requests >= 2.21.0",
|
|
27
27
|
"websocket-client >= 0.54.0",
|
|
28
28
|
]
|
|
29
|
-
asyncio_client = [
|
|
30
|
-
|
|
29
|
+
asyncio_client = [
|
|
30
|
+
"aiohttp >= 3.11"
|
|
31
|
+
]
|
|
32
|
+
dev = [
|
|
33
|
+
"tox",
|
|
34
|
+
]
|
|
35
|
+
docs = [
|
|
36
|
+
"sphinx",
|
|
37
|
+
"furo",
|
|
38
|
+
]
|
|
31
39
|
|
|
32
40
|
[tool.setuptools]
|
|
33
41
|
zip-safe = false
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
from http.cookies import SimpleCookie
|
|
3
|
+
import inspect
|
|
2
4
|
import signal
|
|
3
5
|
import ssl
|
|
4
6
|
import threading
|
|
@@ -53,10 +55,11 @@ class AsyncClient(base_client.BaseClient):
|
|
|
53
55
|
use. To disable logging set to ``False``. The default is
|
|
54
56
|
``False``. Note that fatal errors are logged even when
|
|
55
57
|
``logger`` is ``False``.
|
|
56
|
-
:param json: An alternative
|
|
58
|
+
:param json: An alternative JSON module to use for encoding and decoding
|
|
57
59
|
packets. Custom json modules must have ``dumps`` and ``loads``
|
|
58
60
|
functions that are compatible with the standard library
|
|
59
|
-
versions.
|
|
61
|
+
versions. This is a process-wide setting, all instantiated
|
|
62
|
+
servers and clients must use the same JSON module.
|
|
60
63
|
:param request_timeout: A timeout in seconds for requests. The default is
|
|
61
64
|
5 seconds.
|
|
62
65
|
:param http_session: an initialized ``aiohttp.ClientSession`` object to be
|
|
@@ -319,16 +322,16 @@ class AsyncClient(base_client.BaseClient):
|
|
|
319
322
|
|
|
320
323
|
# extract any new cookies passed in a header so that they can also be
|
|
321
324
|
# sent the the WebSocket route
|
|
322
|
-
cookies = {}
|
|
323
325
|
for header, value in headers.items():
|
|
324
326
|
if header.lower() == 'cookie':
|
|
325
|
-
|
|
326
|
-
|
|
327
|
+
ck = SimpleCookie(headers[header])
|
|
328
|
+
self.http.cookie_jar.update_cookies(
|
|
329
|
+
{k: m.value for k, m in ck.items()})
|
|
327
330
|
del headers[header]
|
|
328
331
|
break
|
|
329
|
-
self.http.cookie_jar.update_cookies(cookies)
|
|
330
332
|
|
|
331
|
-
extra_options = {
|
|
333
|
+
extra_options = {
|
|
334
|
+
'timeout': aiohttp.ClientWSTimeout(ws_close=self.request_timeout)}
|
|
332
335
|
if not self.ssl_verify:
|
|
333
336
|
ssl_context = ssl.create_default_context()
|
|
334
337
|
ssl_context.check_hostname = False
|
|
@@ -468,7 +471,7 @@ class AsyncClient(base_client.BaseClient):
|
|
|
468
471
|
run_async = kwargs.pop('run_async', False)
|
|
469
472
|
ret = None
|
|
470
473
|
if event in self.handlers:
|
|
471
|
-
if
|
|
474
|
+
if inspect.iscoroutinefunction(self.handlers[event]) is True:
|
|
472
475
|
if run_async:
|
|
473
476
|
task = self.start_background_task(self.handlers[event],
|
|
474
477
|
*args)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import inspect
|
|
2
2
|
import sys
|
|
3
|
-
from urllib.parse import urlsplit
|
|
4
3
|
|
|
5
4
|
from aiohttp.web import Response, WebSocketResponse
|
|
6
5
|
|
|
@@ -22,12 +21,8 @@ def translate_request(request):
|
|
|
22
21
|
"""This function takes the arguments passed to the request handler and
|
|
23
22
|
uses them to generate a WSGI compatible environ dictionary.
|
|
24
23
|
"""
|
|
25
|
-
message = request._message
|
|
26
|
-
payload = request._payload
|
|
27
|
-
|
|
28
|
-
uri_parts = urlsplit(message.path)
|
|
29
24
|
environ = {
|
|
30
|
-
'wsgi.input':
|
|
25
|
+
'wsgi.input': request.content,
|
|
31
26
|
'wsgi.errors': sys.stderr,
|
|
32
27
|
'wsgi.version': (1, 0),
|
|
33
28
|
'wsgi.async': True,
|
|
@@ -35,10 +30,10 @@ def translate_request(request):
|
|
|
35
30
|
'wsgi.multiprocess': False,
|
|
36
31
|
'wsgi.run_once': False,
|
|
37
32
|
'SERVER_SOFTWARE': 'aiohttp',
|
|
38
|
-
'REQUEST_METHOD':
|
|
39
|
-
'QUERY_STRING':
|
|
40
|
-
'RAW_URI':
|
|
41
|
-
'SERVER_PROTOCOL': 'HTTP
|
|
33
|
+
'REQUEST_METHOD': request.method,
|
|
34
|
+
'QUERY_STRING': request.query_string or '',
|
|
35
|
+
'RAW_URI': request.path_qs,
|
|
36
|
+
'SERVER_PROTOCOL': f'HTTP/{request.version[0]}.{request.version[1]}',
|
|
42
37
|
'REMOTE_ADDR': '127.0.0.1',
|
|
43
38
|
'REMOTE_PORT': '0',
|
|
44
39
|
'SERVER_NAME': 'aiohttp',
|
|
@@ -46,7 +41,7 @@ def translate_request(request):
|
|
|
46
41
|
'aiohttp.request': request
|
|
47
42
|
}
|
|
48
43
|
|
|
49
|
-
for hdr_name, hdr_value in
|
|
44
|
+
for hdr_name, hdr_value in request.headers.items():
|
|
50
45
|
hdr_name = hdr_name.upper()
|
|
51
46
|
if hdr_name == 'CONTENT-TYPE':
|
|
52
47
|
environ['CONTENT_TYPE'] = hdr_value
|
|
@@ -63,9 +58,7 @@ def translate_request(request):
|
|
|
63
58
|
|
|
64
59
|
environ['wsgi.url_scheme'] = environ.get('HTTP_X_FORWARDED_PROTO', 'http')
|
|
65
60
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
environ['PATH_INFO'] = path_info
|
|
61
|
+
environ['PATH_INFO'] = request.path
|
|
69
62
|
environ['SCRIPT_NAME'] = ''
|
|
70
63
|
|
|
71
64
|
return environ
|
|
@@ -105,7 +98,7 @@ class WebSocket: # pragma: no cover
|
|
|
105
98
|
f = self._sock.send_bytes
|
|
106
99
|
else:
|
|
107
100
|
f = self._sock.send_str
|
|
108
|
-
if
|
|
101
|
+
if inspect.iscoroutinefunction(f):
|
|
109
102
|
await f(message)
|
|
110
103
|
else:
|
|
111
104
|
f(message)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import inspect
|
|
1
2
|
import os
|
|
2
3
|
import sys
|
|
3
|
-
import asyncio
|
|
4
4
|
|
|
5
5
|
from engineio.static_files import get_static_file
|
|
6
6
|
|
|
@@ -102,7 +102,7 @@ class ASGIApp:
|
|
|
102
102
|
if self.on_startup:
|
|
103
103
|
try:
|
|
104
104
|
await self.on_startup() \
|
|
105
|
-
if
|
|
105
|
+
if inspect.iscoroutinefunction(self.on_startup) \
|
|
106
106
|
else self.on_startup()
|
|
107
107
|
except:
|
|
108
108
|
await send({'type': 'lifespan.startup.failed'})
|
|
@@ -112,7 +112,7 @@ class ASGIApp:
|
|
|
112
112
|
if self.on_shutdown:
|
|
113
113
|
try:
|
|
114
114
|
await self.on_shutdown() \
|
|
115
|
-
if
|
|
115
|
+
if inspect.iscoroutinefunction(self.on_shutdown) \
|
|
116
116
|
else self.on_shutdown()
|
|
117
117
|
except:
|
|
118
118
|
await send({'type': 'lifespan.shutdown.failed'})
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import inspect
|
|
2
3
|
import sys
|
|
3
4
|
from urllib.parse import urlsplit
|
|
4
5
|
from .. import exceptions
|
|
@@ -24,7 +25,7 @@ def get_tornado_handler(engineio_server):
|
|
|
24
25
|
async def get(self, *args, **kwargs):
|
|
25
26
|
if self.request.headers.get('Upgrade', '').lower() == 'websocket':
|
|
26
27
|
ret = super().get(*args, **kwargs)
|
|
27
|
-
if
|
|
28
|
+
if inspect.iscoroutine(ret):
|
|
28
29
|
await ret
|
|
29
30
|
else:
|
|
30
31
|
await engineio_server.handle_request(self)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import inspect
|
|
2
3
|
import urllib
|
|
3
4
|
|
|
4
5
|
from . import base_server
|
|
@@ -63,10 +64,11 @@ class AsyncServer(base_server.BaseServer):
|
|
|
63
64
|
:param logger: To enable logging set to ``True`` or pass a logger object to
|
|
64
65
|
use. To disable logging set to ``False``. Note that fatal
|
|
65
66
|
errors are logged even when ``logger`` is ``False``.
|
|
66
|
-
:param json: An alternative
|
|
67
|
-
packets. Custom
|
|
67
|
+
:param json: An alternative JSON module to use for encoding and decoding
|
|
68
|
+
packets. Custom JSON modules must have ``dumps`` and ``loads``
|
|
68
69
|
functions that are compatible with the standard library
|
|
69
|
-
versions.
|
|
70
|
+
versions. This is a process-wide setting, all instantiated
|
|
71
|
+
servers and clients must use the same JSON module.
|
|
70
72
|
:param async_handlers: If set to ``True``, run message event handlers in
|
|
71
73
|
non-blocking threads. To run handlers synchronously,
|
|
72
74
|
set to ``False``. The default is ``True``.
|
|
@@ -212,7 +214,7 @@ class AsyncServer(base_server.BaseServer):
|
|
|
212
214
|
Note: this method is a coroutine.
|
|
213
215
|
"""
|
|
214
216
|
translate_request = self._async['translate_request']
|
|
215
|
-
if
|
|
217
|
+
if inspect.iscoroutinefunction(translate_request):
|
|
216
218
|
environ = await translate_request(*args, **kwargs)
|
|
217
219
|
else:
|
|
218
220
|
environ = translate_request(*args, **kwargs)
|
|
@@ -427,7 +429,7 @@ class AsyncServer(base_server.BaseServer):
|
|
|
427
429
|
async def _make_response(self, response_dict, environ):
|
|
428
430
|
cors_headers = self._cors_headers(environ)
|
|
429
431
|
make_response = self._async['make_response']
|
|
430
|
-
if
|
|
432
|
+
if inspect.iscoroutinefunction(make_response):
|
|
431
433
|
response = await make_response(
|
|
432
434
|
response_dict['status'],
|
|
433
435
|
response_dict['headers'] + cors_headers,
|
|
@@ -502,7 +504,7 @@ class AsyncServer(base_server.BaseServer):
|
|
|
502
504
|
run_async = kwargs.pop('run_async', False)
|
|
503
505
|
ret = None
|
|
504
506
|
if event in self.handlers:
|
|
505
|
-
if
|
|
507
|
+
if inspect.iscoroutinefunction(self.handlers[event]):
|
|
506
508
|
async def run_async_handler():
|
|
507
509
|
try:
|
|
508
510
|
try:
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from base64 import b64encode
|
|
2
|
-
from
|
|
2
|
+
from http.cookies import SimpleCookie
|
|
3
3
|
import logging
|
|
4
4
|
import queue
|
|
5
5
|
import ssl
|
|
6
6
|
import threading
|
|
7
7
|
import time
|
|
8
8
|
import urllib
|
|
9
|
+
from engineio.json import JSONDecodeError
|
|
9
10
|
|
|
10
11
|
try:
|
|
11
12
|
import requests
|
|
@@ -33,10 +34,11 @@ class Client(base_client.BaseClient):
|
|
|
33
34
|
use. To disable logging set to ``False``. The default is
|
|
34
35
|
``False``. Note that fatal errors are logged even when
|
|
35
36
|
``logger`` is ``False``.
|
|
36
|
-
:param json: An alternative
|
|
37
|
+
:param json: An alternative JSON module to use for encoding and decoding
|
|
37
38
|
packets. Custom json modules must have ``dumps`` and ``loads``
|
|
38
39
|
functions that are compatible with the standard library
|
|
39
|
-
versions.
|
|
40
|
+
versions. This is a process-wide setting, all instantiated
|
|
41
|
+
servers and clients must use the same JSON module.
|
|
40
42
|
:param request_timeout: A timeout in seconds for requests. The default is
|
|
41
43
|
5 seconds.
|
|
42
44
|
:param http_session: an initialized ``requests.Session`` object to be used
|
|
@@ -268,8 +270,10 @@ class Client(base_client.BaseClient):
|
|
|
268
270
|
extra_options = {}
|
|
269
271
|
if self.http:
|
|
270
272
|
# cookies
|
|
271
|
-
|
|
272
|
-
|
|
273
|
+
ck = SimpleCookie()
|
|
274
|
+
for cookie in self.http.cookies:
|
|
275
|
+
ck[cookie.name] = cookie.value
|
|
276
|
+
cookies = ck.output(header='', sep=';').strip()
|
|
273
277
|
for header, value in headers.items():
|
|
274
278
|
if header.lower() == 'cookie':
|
|
275
279
|
if cookies:
|
|
@@ -63,10 +63,11 @@ class Server(base_server.BaseServer):
|
|
|
63
63
|
use. To disable logging set to ``False``. The default is
|
|
64
64
|
``False``. Note that fatal errors are logged even when
|
|
65
65
|
``logger`` is ``False``.
|
|
66
|
-
:param json: An alternative
|
|
67
|
-
packets. Custom
|
|
66
|
+
:param json: An alternative JSON module to use for encoding and decoding
|
|
67
|
+
packets. Custom JSON modules must have ``dumps`` and ``loads``
|
|
68
68
|
functions that are compatible with the standard library
|
|
69
|
-
versions.
|
|
69
|
+
versions. This is a process-wide setting, all instantiated
|
|
70
|
+
servers and clients must use the same JSON module.
|
|
70
71
|
:param async_handlers: If set to ``True``, run message event handlers in
|
|
71
72
|
non-blocking threads. To run handlers synchronously,
|
|
72
73
|
set to ``False``. The default is ``True``.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-engineio
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.13.1
|
|
4
4
|
Summary: Engine.IO server and client for Python
|
|
5
5
|
Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -10,7 +10,7 @@ Classifier: Environment :: Web Environment
|
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
|
-
Requires-Python: >=3.
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
Requires-Dist: simple-websocket>=0.10.0
|
|
@@ -18,9 +18,12 @@ Provides-Extra: client
|
|
|
18
18
|
Requires-Dist: requests>=2.21.0; extra == "client"
|
|
19
19
|
Requires-Dist: websocket-client>=0.54.0; extra == "client"
|
|
20
20
|
Provides-Extra: asyncio-client
|
|
21
|
-
Requires-Dist: aiohttp>=3.
|
|
21
|
+
Requires-Dist: aiohttp>=3.11; extra == "asyncio-client"
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: tox; extra == "dev"
|
|
22
24
|
Provides-Extra: docs
|
|
23
25
|
Requires-Dist: sphinx; extra == "docs"
|
|
26
|
+
Requires-Dist: furo; extra == "docs"
|
|
24
27
|
Dynamic: license-file
|
|
25
28
|
|
|
26
29
|
python-engineio
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from unittest import mock
|
|
2
2
|
|
|
3
|
+
import yarl
|
|
4
|
+
from aiohttp.web import Request
|
|
5
|
+
|
|
3
6
|
from engineio.async_drivers import aiohttp as async_aiohttp
|
|
4
7
|
|
|
5
8
|
|
|
@@ -12,18 +15,28 @@ class TestAiohttp:
|
|
|
12
15
|
app.router.add_post.assert_any_call('/foo', mock_server.handle_request)
|
|
13
16
|
|
|
14
17
|
def test_translate_request(self):
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
message = mock.MagicMock()
|
|
19
|
+
message.url = yarl.URL('https://example.com/foo/bar?baz=1')
|
|
20
|
+
message.method = 'PUT'
|
|
21
|
+
message.path = '/foo/bar?baz=1'
|
|
22
|
+
message.version = (1, 1)
|
|
23
|
+
message.headers = {
|
|
20
24
|
'a': 'b',
|
|
21
25
|
'c-c': 'd',
|
|
22
26
|
'c_c': 'e',
|
|
23
27
|
'content-type': 'application/json',
|
|
24
28
|
'content-length': 123,
|
|
25
29
|
}
|
|
26
|
-
|
|
30
|
+
|
|
31
|
+
request = Request(
|
|
32
|
+
message,
|
|
33
|
+
payload=b'hello world',
|
|
34
|
+
protocol=mock.MagicMock(),
|
|
35
|
+
payload_writer=mock.MagicMock(),
|
|
36
|
+
task=mock.MagicMock(),
|
|
37
|
+
loop=mock.MagicMock(),
|
|
38
|
+
)
|
|
39
|
+
|
|
27
40
|
environ = async_aiohttp.translate_request(request)
|
|
28
41
|
expected_environ = {
|
|
29
42
|
'REQUEST_METHOD': 'PUT',
|
|
@@ -24,6 +24,10 @@ class TestAsyncClient:
|
|
|
24
24
|
client.queue.put = mock.AsyncMock()
|
|
25
25
|
client.queue.join = mock.AsyncMock()
|
|
26
26
|
|
|
27
|
+
@staticmethod
|
|
28
|
+
def mock_ws_timeout(ws_close):
|
|
29
|
+
return ws_close
|
|
30
|
+
|
|
27
31
|
async def test_is_asyncio_based(self):
|
|
28
32
|
c = async_client.AsyncClient()
|
|
29
33
|
assert c.is_asyncio_based()
|
|
@@ -500,6 +504,8 @@ class TestAsyncClient:
|
|
|
500
504
|
assert c in base_client.connected_clients
|
|
501
505
|
|
|
502
506
|
@mock.patch('engineio.client.time.time', return_value=123.456)
|
|
507
|
+
@mock.patch('engineio.async_client.aiohttp.ClientWSTimeout',
|
|
508
|
+
new=mock_ws_timeout)
|
|
503
509
|
async def test_websocket_connection_failed(self, _time):
|
|
504
510
|
c = async_client.AsyncClient()
|
|
505
511
|
c.http = mock.MagicMock(closed=False)
|
|
@@ -541,6 +547,8 @@ class TestAsyncClient:
|
|
|
541
547
|
)
|
|
542
548
|
|
|
543
549
|
@mock.patch('engineio.client.time.time', return_value=123.456)
|
|
550
|
+
@mock.patch('engineio.async_client.aiohttp.ClientWSTimeout',
|
|
551
|
+
new=mock_ws_timeout)
|
|
544
552
|
async def test_websocket_upgrade_failed(self, _time):
|
|
545
553
|
c = async_client.AsyncClient()
|
|
546
554
|
c.http = mock.MagicMock(closed=False)
|
|
@@ -568,6 +576,8 @@ class TestAsyncClient:
|
|
|
568
576
|
await c.connect('http://foo', transports=['websocket'])
|
|
569
577
|
|
|
570
578
|
@mock.patch('engineio.client.time.time', return_value=123.456)
|
|
579
|
+
@mock.patch('engineio.async_client.aiohttp.ClientWSTimeout',
|
|
580
|
+
new=mock_ws_timeout)
|
|
571
581
|
async def test_websocket_connection_successful(self, _time):
|
|
572
582
|
c = async_client.AsyncClient()
|
|
573
583
|
c.http = mock.MagicMock(closed=False)
|
|
@@ -649,6 +659,8 @@ class TestAsyncClient:
|
|
|
649
659
|
assert kwargs['ssl'].verify_mode == ssl.CERT_NONE
|
|
650
660
|
|
|
651
661
|
@mock.patch('engineio.client.time.time', return_value=123.456)
|
|
662
|
+
@mock.patch('engineio.async_client.aiohttp.ClientWSTimeout',
|
|
663
|
+
new=mock_ws_timeout)
|
|
652
664
|
async def test_websocket_connection_with_cookies(self, _time):
|
|
653
665
|
c = async_client.AsyncClient()
|
|
654
666
|
c.http = mock.MagicMock(closed=False)
|
|
@@ -682,6 +694,8 @@ class TestAsyncClient:
|
|
|
682
694
|
)
|
|
683
695
|
|
|
684
696
|
@mock.patch('engineio.client.time.time', return_value=123.456)
|
|
697
|
+
@mock.patch('engineio.async_client.aiohttp.ClientWSTimeout',
|
|
698
|
+
new=mock_ws_timeout)
|
|
685
699
|
async def test_websocket_connection_with_cookie_header(self, _time):
|
|
686
700
|
c = async_client.AsyncClient()
|
|
687
701
|
c.http = mock.MagicMock(closed=False)
|
|
@@ -714,10 +728,12 @@ class TestAsyncClient:
|
|
|
714
728
|
timeout=5,
|
|
715
729
|
)
|
|
716
730
|
c.http.cookie_jar.update_cookies.assert_called_once_with(
|
|
717
|
-
{'key': 'value', 'key2': 'value2', 'key3': '
|
|
731
|
+
{'key': 'value', 'key2': 'value2', 'key3': 'value3='}
|
|
718
732
|
)
|
|
719
733
|
|
|
720
734
|
@mock.patch('engineio.client.time.time', return_value=123.456)
|
|
735
|
+
@mock.patch('engineio.async_client.aiohttp.ClientWSTimeout',
|
|
736
|
+
new=mock_ws_timeout)
|
|
721
737
|
async def test_websocket_connection_with_cookies_and_headers(self, _time):
|
|
722
738
|
c = async_client.AsyncClient()
|
|
723
739
|
c.http = mock.MagicMock(closed=False)
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
[tox]
|
|
2
|
-
envlist=flake8,
|
|
2
|
+
envlist=flake8,py310,py311,py312,py313,py314,pypy3,docs
|
|
3
3
|
skip_missing_interpreters=True
|
|
4
4
|
|
|
5
5
|
[gh-actions]
|
|
6
6
|
python =
|
|
7
|
-
3.8: py38
|
|
8
|
-
3.9: py39
|
|
9
7
|
3.10: py310
|
|
10
8
|
3.11: py311
|
|
11
9
|
3.12: py312
|
|
12
10
|
3.13: py313
|
|
11
|
+
3.14: py314
|
|
13
12
|
pypy-3: pypy3
|
|
14
13
|
|
|
15
14
|
[testenv]
|
|
@@ -37,6 +36,7 @@ commands=
|
|
|
37
36
|
changedir=docs
|
|
38
37
|
deps=
|
|
39
38
|
sphinx
|
|
39
|
+
furo
|
|
40
40
|
allowlist_externals=
|
|
41
41
|
make
|
|
42
42
|
commands=
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
API Reference
|
|
2
|
-
=============
|
|
3
|
-
|
|
4
|
-
.. toctree::
|
|
5
|
-
:maxdepth: 3
|
|
6
|
-
|
|
7
|
-
.. module:: engineio
|
|
8
|
-
|
|
9
|
-
.. autoclass:: Client
|
|
10
|
-
:members:
|
|
11
|
-
:inherited-members:
|
|
12
|
-
|
|
13
|
-
.. autoclass:: AsyncClient
|
|
14
|
-
:members:
|
|
15
|
-
:inherited-members:
|
|
16
|
-
|
|
17
|
-
.. autoclass:: Server
|
|
18
|
-
:members:
|
|
19
|
-
:inherited-members:
|
|
20
|
-
|
|
21
|
-
.. autoclass:: AsyncServer
|
|
22
|
-
:members:
|
|
23
|
-
:inherited-members:
|
|
24
|
-
|
|
25
|
-
.. autoclass:: WSGIApp
|
|
26
|
-
:members:
|
|
27
|
-
|
|
28
|
-
.. autoclass:: ASGIApp
|
|
29
|
-
:members:
|
|
30
|
-
|
|
31
|
-
.. autoclass:: Middleware
|
|
32
|
-
:members:
|
|
33
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/_websocket_wsgi.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_engineio-4.12.3 → python_engineio-4.13.1}/src/engineio/async_drivers/gevent_uwsgi.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_engineio-4.12.3 → python_engineio-4.13.1}/src/python_engineio.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{python_engineio-4.12.3 → python_engineio-4.13.1}/src/python_engineio.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|