Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

websockets: unexpected keyword connections #2977

Open
1 task done
benjiqq opened this issue Jun 28, 2024 · 1 comment
Open
1 task done

websockets: unexpected keyword connections #2977

benjiqq opened this issue Jun 28, 2024 · 1 comment
Labels

Comments

@benjiqq
Copy link

benjiqq commented Jun 28, 2024

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

@benjiqq benjiqq added the bug label Jun 28, 2024
@ashleysommer
Copy link
Member

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) 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants