I am trying to deploy my flask app on a headless pi. My flask app uses Socketio to create websockets to push sensor data to my routes. I also also use flask WTForms in my flask app. The flask app functioned as expected when running locally on my laptop.

My challenge is to deploy the flask app to my pi using Nginx and Gunicorn so that the http requests and websockets both work.

I have deployed on my pi using Nginx and Gunicorn. When I used the standard gunicorn worker class, the app forms all functioned correctly, but the websockets were not being established. I corrected this by using the worker class geventwebsocket.gunicorn.workers.GeventWebSocketWorker. This established the websocket connection and enabled the real time data to be pushed to my flask app, but now none of the forms function, I assume the http requests are being blocked.

Do I need to use multiple workers, and therefore implement a message queue?

my Gunicorn service:

[Unit]
Description=Gunicorn instance to serve myproject Flask app
Requires=flask_app.socket
After=network.target

[Service]
User=pi
Group=www-data
WorkingDirectory=/home/pi/myproject
Environment="PATH=/home/pi/myproject/env/bin"
ExecStart=/home/pi/myproject/env/bin/gunicorn --workers 1 --bind unix:/home/pi/myproject/flask_app.sock -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker --log-file /home/pi/myproject/gunicorn.log wsgi:app

[Install]
WantedBy=multi-user.target

My Nginx configuration is:

server {
    listen 80;

    server_name localhost.local www.localhost.local;

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/pi/myproject/flask_app.sock;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400;

 }

   location /socket.io {
        include proxy_params;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_pass http://unix:/home/pi/myproject/flask_app.sock;
        proxy_read_timeout 86400;
        proxy_buffering off;  # Disable buffering for WebSocket connections
   }
}

snippets from my flask app showing the socket connection:

from gevent import monkey
monkey.patch_all()

app = Flask(__name__)

socketio = SocketIO(app, async_mode='gevent')

@socketio.on('connect', namespace='/display')
def handle_display_connect():
    try:    
        
        
        table_data, data,  = fetch_display_data()
        


        socketio.emit('display_data', {
            'display_table_data': table_data,
            'display_charts_data': data,
            
        }, namespace='/display')

        #start background task
        gevent_task = spawn(emit_display_data)
        gevent_task.start()
        socket_tasks_display[request.sid] = gevent_task


        

    except Exception as e:
        # Handle connection error
        print(f"Error during connection: {str(e)}")
        socketio.emit('error', {'message': 'Connection error'}, namespace='/display')


if __name__ =='__main__':
                
    socketio.run(app, host='0.0.0.0', port=5000, debug=True)

Any thoughts would be very much appreciated.

0

There are 0 best solutions below