Deploying a multi-user Dashboard

cuXfilter dashboard when run from a jupyter/jupyterlab notebook, can be run as a single session temporary dashboard within the context of the notebook session. Since it is a Bokeh web application, it is also possible to run it as a multi-instance, multi-user dashboard behind a load balancer (e.g: nginx load balancer).


Running the auto_accidents dashboard behind a local load balancer:

from bokeh.server.server import Server
import cuxfilter
import sys

DATA_DIR = './data'

cux_df = cuxfilter.DataFrame.from_arrow(DATA_DIR+'/auto_accidents.arrow')['ST_CASE'] =['ST_CASE'].astype('float64')

def bkapp(doc):
    global cux_df
    label_map = {1: 'Sunday',    2: 'Monday',    3: 'Tuesday',    4: 'Wednesday',   5: 'Thursday',    6: 'Friday',    7: 'Saturday',    9: 'Unknown'}
    gtc_demo_red_blue_palette = [ (49,130,189), (107,174,214), (123, 142, 216), (226,103,152), (255,0,104) , (50,50,50) ]

    # declare charts
    chart1 = cuxfilter.charts.scatter(x='dropoff_x', y='dropoff_y', aggregate_col='ST_CASE',
    chart2 = cuxfilter.charts.multi_select('YEAR')
    chart3 ='DAY_WEEK', x_label_map=label_map)
    chart4 ='MONTH')

    # declare dashboard
    d = cux_df.dashboard([chart1, chart2, chart3, chart4], layout=cuxfilter.layouts.feature_and_double_base,theme = cuxfilter.themes.light, title='Auto Accident Dataset')

    # run the dashboard as a webapp:
        d.title, d._charts, d._theme

if __name__ == '__main__':
    server = Server({'/custom_dashboard': bkapp}, num_procs=1, allow_websocket_origin=[""])

    print('running server on port '+str(port))

Load balancing

Based on Bokeh deployment documentation mentioned here, we can setup load balancing with nginx reverse proxying setup.

Example nginx.conf

upstream demos {

server {
    listen 80 default_server;
    server_name _;

    location / {
        proxy_pass http://demos;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host:$server_port;
        proxy_buffering off;


Run the above as a python script:

python 5000
python 5001