Elegant WebSockets for your Flask apps.
Go to file
Derek 98ba141f7d Add build and twine as dev deps for easy publishing 2022-01-15 16:49:27 -07:00
.gitignore Add support of Flask blueprints 2016-05-01 17:13:49 +03:00
LICENSE flask-sockets 2013-09-30 21:01:22 -04:00
Pipfile Add build and twine as dev deps for easy publishing 2022-01-15 16:49:27 -07:00
Pipfile.lock Add build and twine as dev deps for easy publishing 2022-01-15 16:49:27 -07:00
README.md Bump version, prep for pypi 2022-01-15 16:20:00 -07:00
flask_sockets.py Add SCRIPT_NAME support 2022-01-15 16:11:48 -07:00
setup.py Setup pipenv 2022-01-15 16:30:41 -07:00

README.md

Flask-Sockets

Elegant WebSockets for your Flask apps. A (hopefully) maintained fork of https://github.com/heroku-python/flask-sockets

Cover image

Simple usage of route decorator:


    from flask import Flask
    from flask_sockets import Sockets


    app = Flask(__name__)
    sockets = Sockets(app)


    @sockets.route('/echo')
    def echo_socket(ws):
        while not ws.closed:
            message = ws.receive()
            ws.send(message)


    @app.route('/')
    def hello():
        return 'Hello World!'


    if __name__ == "__main__":
        from gevent import pywsgi
        from geventwebsocket.handler import WebSocketHandler
        server = pywsgi.WSGIServer(('', 5000), app, handler_class=WebSocketHandler)
        server.serve_forever()

Usage of Flask blueprints:


    from flask import Flask, Blueprint
    from flask_sockets import Sockets


    html = Blueprint(r'html', __name__)
    ws = Blueprint(r'ws', __name__)


    @html.route('/')
    def hello():
        return 'Hello World!'

    @ws.route('/echo')
    def echo_socket(socket):
        while not socket.closed:
            message = socket.receive()
            socket.send(message)


    app = Flask(__name__)
    sockets = Sockets(app)

    app.register_blueprint(html, url_prefix=r'/')
    sockets.register_blueprint(ws, url_prefix=r'/')


    if __name__ == "__main__":
        from gevent import pywsgi
        from geventwebsocket.handler import WebSocketHandler
        server = pywsgi.WSGIServer(('', 5000), app, handler_class=WebSocketHandler)
        server.serve_forever()

Combining WebSockets with Ajax (XHR) endpoints also comes handy with the support of session handling built-in to sockets as well. As an example you could use an Ajax login call which would create a new session and accordingly set a secure HttpOnly cookie to the browser. After authorization, you can connect to the WebSocket endpoint and reuse the session handling from Flask there as well (as shown here: https://pythonhosted.org/Flask-Session/). Access to other custom cookies is also possible via Flasks request.cookies property.

Serving WebSockets in Python was really difficult. Now it's not.

Installation

To install Flask-Sockets, simply:

$ pip install Flask-Sockets

Deployment

A custom Gunicorn worker is included to make deployment as friendly as possible::

$ gunicorn -k flask_sockets.worker hello:app

Production services are provided by gevent and gevent-websocket.

The given example can run standalone as main.

Anything that inserts wsgi.websocket into the WSGI environ is supported, but gevent-websocket is recommended.

Development / Testing

Because the Werkzeug development server cannot provide the WSGI environ with a websocket interface, it is not possible to run a Flask app using the standard app.run().

If you try to, Flask will still try to serve on all the specified routes, and throw a KeyError whenever a client tries to connect to a websocket route.

Instead, just use the included gunicorn worker (explained above), or anything that can insert wsgi.websocket into the WSGI environ.

WebSocket Interface

The websocket interface that is passed into your routes is provided by gevent-websocket. The basic methods are fairly straightforward —  send, receive, send_frame, and close.

Release History

v0.2.2

  • Add support for SCRIPT_NAME

v0.2.1

v0.2.0

  • Add request context into the socket handler.
  • Fallback to Flask logic if websocket environment is not available.
  • Use Flask routing to allow for variables in URL

v0.1.0

  • Initial release.