websockets: unexpected keyword connections
benjiqq opened this issue · comments
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
websockets: unexpected keyword connections
debug log
/root/.cache/pypoetry/virtualenvs/webserver-Mns4wmqm-py3.12/lib/python3.12/site-packages/sanic/touchup/schemes/ode.py:70: DeprecationWarning: Attribute s is deprecated and will be removed in Python 3.14; use value instead
if hasattr(event, "s"):
[2024-06-28 08:36:47 +0000] [49052] [INFO] Starting worker [49052]
Unhandled exception in event loop
Traceback (most recent call last):
File "uvloop/handles/streamserver.pyx", line 148, in uvloop.loop.__uv_streamserver_on_listen
File "uvloop/handles/streamserver.pyx", line 69, in uvloop.loop.UVStreamServer._on_listen
File "uvloop/loop.pyx", line 101, in uvloop.loop.run_in_context
TypeError: WebsocketImplProtocol.__init__() got an unexpected keyword argument 'connections'
code
from sanic import Sanic, response
from sanic.response import json, file
from sanic import Request, Websocket
from datetime import datetime
import json # Ensure you import json
import asyncio
app = Sanic("webserver")
@app.websocket("/feed")
async def feed(request: Request, ws: Websocket):
while True:
data = "hello!"
print("Sending: " + data)
await ws.send(data)
data = await ws.recv()
print("Received: " + data)
if __name__ == "__main__":
webport = 9000
print(f"Starting app on port {webport}")
app.run(host="0.0.0.0", port=int(webport), protocol=Websocket)
versions
poetry show sanic
name : sanic
version : 23.12.1
...
uvloop
name : uvloop
version : 0.19.0
Code snippet
No response
Expected Behavior
No response
How do you run Sanic?
As a module
Operating System
Linux
Sanic Version
23.12.1
Additional context
No response
Hi @benjiqq
Did you copy-paste this snippet from somewhere or did you write it yourself?
When you do from sanic import Websocket
like you've done, that is actually importing the Request/Response WS implementation WebSocketImpl
from here:
sanic/sanic/server/websockets/impl.py
Line 44 in 90e3beb
That works to act as the correct type hint for the ws
argument in your feed handler, but it is not the correct class to pass into sanic's app.run()
for protocol=Websocket
.
Normally when serving a websocket endpoint, we don't need to manually specify the WebSocketProtocol
protocol in the app runner. The default sanic HttpProtocol
will honor the HTTP Connection=upgrade
header and automatically upgrade its protocol to WebSocketProtocol
where required.
If you really do want a full WebSocket-only deployment where you have a bare websocket-only client that does not need to mess with HTTP Connection=upgrade
business, then you can set it up like this:
from sanic import Sanic, response
from sanic import Request, Websocket
from sanic.server.protocols.websocket_protocol import WebSocketProtocol
app = Sanic("webserver")
@app.websocket("/feed")
async def feed(request: Request, ws: Websocket):
while True:
data = "hello!"
print("Sending: " + data)
await ws.send(data)
data = await ws.recv()
print("Received: " + data)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, protocol=WebSocketProtocol)