sanic-org / sanic

Accelerate your web app development | Build fast. Run fast.

Home Page:https://sanic.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

websockets: unexpected keyword connections

benjiqq opened this issue · comments

commented

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:

class WebsocketImplProtocol:

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)