Proxy errors due to improper inference of `websockets` version (based on Python version)
See original GitHub issueChecklist
- The bug is reproducible against the latest release or
master
. - There are no similar issues or pull requests to fix it yet.
Describe the bug
With Python >= 3.7 and websockets
<10, websockets
is passed a logger parameter that the legacy server does not support.
The _LoggerMixin
class is required to prevent the logger from being passed into the legacy server that websockets
uses in earlier (<10) versions. Not having the mixin yields the following error:
Fatal error: protocol.data_received() call failed.
protocol: <uvicorn.protocols.http.h11_impl.H11Protocol object at 0x104daa910>
transport: <_SelectorSocketTransport fd=22 read=polling write=<idle, bufsize=0>>
Traceback (most recent call last):
File "/Users/shy/.pyenv/versions/3.9.6/lib/python3.9/asyncio/selector_events.py", line 870, in _read_ready__data_received
self._protocol.data_received(data)
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 131, in data_received
self.handle_events()
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 180, in handle_events
self.handle_upgrade(event)
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 268, in handle_upgrade
protocol = self.ws_protocol_class(
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 77, in __init__
super().__init__(
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/websockets/legacy/server.py", line 201, in __init__
super().__init__(**kwargs)
TypeError: __init__() got an unexpected keyword argument 'logger'
which results in errors proxying sockets on the frontend:
Proxy error: Could not proxy request /socket.io/?EIO=4&transport=polling&t=NvBQjFH from localhost:3000 to http://127.0.0.1:8080/.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).
The class is implemented in /uvicorn/protocols/websockets/websockets_impl.py
and infers the version of websockets from the Python version. Websockets conforms to PEP8’s __version__
so that could be used instead.
# special case logger kwarg in websockets >=10
if sys.version_info >= (3, 7):
class _LoggerMixin:
pass
else:
class _LoggerMixin:
def __init__(self, *args, logger, **kwargs):
super().__init__(*args, **kwargs)
self.logger = logging.LoggerAdapter(logger, {"websocket": self})
Steps to reproduce the bug
Dependencies:
uvicorn==16.0.0
websockets==0.9.1
fastapi==0.70.1
This fails:
from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
app = FastAPI()
html = """
<script>
var ws = new WebSocket("ws://localhost:8000/ws");
</script>
"""
@app.get("/")
async def get():
return HTMLResponse(html)
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message text was: {data}")
Expected behavior
Establishing a connection successfully.
Actual behavior
Pretty much the same error:
Fatal error: protocol.data_received() call failed.
protocol: <uvicorn.protocols.http.h11_impl.H11Protocol object at 0x1067ffc70>
transport: <_SelectorSocketTransport fd=12 read=polling write=<idle, bufsize=0>>
Traceback (most recent call last):
File "/Users/shy/.pyenv/versions/3.9.6/lib/python3.9/asyncio/selector_events.py", line 870, in _read_ready__data_received
self._protocol.data_received(data)
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 131, in data_received
self.handle_events()
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 180, in handle_events
self.handle_upgrade(event)
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 268, in handle_upgrade
protocol = self.ws_protocol_class(
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 77, in __init__
super().__init__(
File "/Users/shy/Projects/nftychat/venv/lib/python3.9/site-packages/websockets/legacy/server.py", line 201, in __init__
super().__init__(**kwargs)
TypeError: __init__() got an unexpected keyword argument 'logger'
Debugging material
No response
Environment
Uvicorn 0.16.0, CPython 3.9.6
uvicorn example:app
fails with the prior snippet.
Additional context
I’m going to make a PR using the dunder.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
Yes, that will resolve the issue.
Well… It was already released.