Search code examples
socket.ioflaskgeventgunicorn

gevent-socketio + Flask + Gunicorn


Can I use gevent-socketio with Flask, running under Gunicorn, and still enjoy the nice exception printing, debugger, and reload capability that Flask offers? How would my gunicorn worker and WSGI app class look like?


Solution

  • I've got the exact same problem so I solved it by using watchdog.

    pip install watchdog
    

    together with this command:

    watchmedo shell-command --patterns="*.py*;;*.less;*.css;*.js;*.txt;*.html" --recursive --command='kill -HUP `cat /tmp/gunicorn.pid` && echo "Reloading code" >> /tmp/gunicorn.log' ~/projectfolder
    

    It requires (well, not really, but I point "Reloading code" into the same logfile so It's a nice thing to have) that you daemonize the gunicorn process, which I do like this:

    gunicorn_config.py

    workers = 2
    worker_class = 'socketio.sgunicorn.GeventSocketIOWorker'
    bind = '0.0.0.0:5000'
    pidfile = '/tmp/gunicorn.pid'
    debug = True
    loglevel = 'debug'
    errorlog = '/tmp/gunicorn.log'
    daemon = True
    

    Start the application:

    gunicorn run:app -c gunicorn-config.py
    

    View the log:

    tail -f /tmp/gunicorn.log
    

    From this point everything should be reloaded with each change in your project. It's a bit complicated but since gunicorn with a worker (or the built in socketio-server) doesn't have any reloading capabilities I had to do it like this.

    It's a different approach compared to the decorator solution in the other answer but I like to keep the actual code clean from development specific solutions. Both accomplish the same thing so I guess you'll just have to pick the solution you like. :)

    Oh, as an added bonus you get to use the production server in development which means both environments match each other.