miguelgrinberg / flask-sock

Modern WebSocket support for Flask.
MIT License
272 stars 24 forks source link

Compatibility with python-livereload? #32

Closed allsey87 closed 2 years ago

allsey87 commented 2 years ago

I have a frontend/backend set up that uses flask-sock and works well when I start my application with:

FLASK_APP=backend FLASK_ENV=development flask run

However, when I try to start my application using the API of python-livereload as follows:

from backend import app
from livereload import Server, shell

if __name__ == '__main__':
    app.debug = True
    server = Server(app.wsgi_app)
    server.watch('backend/static')
    server.serve(port=5000)

I am getting the following back trace:

[E 220719 13:44:59 web:1798] Uncaught exception GET /stream (127.0.0.1)
    HTTPServerRequest(protocol='http', host='localhost:5000', method='GET', uri='/stream', version='HTTP/1.1', remote_ip='127.0.0.1')
    Traceback (most recent call last):
      File "/usr/local/lib/python3.8/dist-packages/tornado/web.py", line 1690, in _execute
        result = self.prepare()
      File "/usr/local/lib/python3.8/dist-packages/tornado/web.py", line 3056, in prepare
        self.fallback(self.request)
      File "/usr/local/lib/python3.8/dist-packages/livereload/server.py", line 112, in __call__
        app_response = self.wsgi_app(
      File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 2076, in wsgi_app
        response = self.handle_exception(e)
      File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 2073, in wsgi_app
        response = self.full_dispatch_request()
      File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1519, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1517, in full_dispatch_request
        rv = self.dispatch_request()
      File "/usr/local/lib/python3.8/dist-packages/flask/app.py", line 1503, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
      File "/usr/local/lib/python3.8/dist-packages/flask_sock/__init__.py", line 56, in websocket_route
        ws = Server(request.environ, **current_app.config.get(
      File "/usr/local/lib/python3.8/dist-packages/simple_websocket/ws.py", line 301, in __init__
        raise RuntimeError('Cannot obtain socket from WSGI environment.')
    RuntimeError: Cannot obtain socket from WSGI environment.

I am not sure how to interpret the error Cannot obtain socket from WSGI environment. As far as I understand, when I use flask run, I am using the Werkzeug framework which is supported by flask-sock and from the back trace python-livereload is using Tornado which perhaps is not supported?

This is all a bit confusing since from #29 it is mentioned:

Flask-Sock uses its own WebSocket implementation (provided by the wsproto package) instead of relying on the web server's own WebSocket support

So I would have thought that it did not matter what underlying framework is being used...

miguelgrinberg commented 2 years ago

You can only use Flask-Sock with the supported web servers, all of which have a method of exposing the network socket. The web server that you are using is not in the supported list, so it cannot be used.

allsey87 commented 2 years ago

@miguelgrinberg would you be able to suggest a setup that includes flask-sock and something akin to python-livereload, i.e., something that causes the browser to reload when the source code has changed?

miguelgrinberg commented 2 years ago

Flask in debug mode reloads on code changes. Isn't that sufficient?

allsey87 commented 2 years ago

As far as I am aware, it only reloads the server (not the browser).

miguelgrinberg commented 2 years ago

Yes, only the server is reloaded, then you have to refresh the browser manually. I don't know of any solution that refreshes the browser as well, sorry.

allsey87 commented 2 years ago

Well, there is the heavy handed solution of bringing in Selenium (in conjunction with watchdog), but I was hoping for something a bit more elegant than that.