Flask gunicorn on debian server


I need some help setting up a bokeh application with flask and gunicorn on a debian server. I never did anything with flask or gunicorn befor.

I have a bokeh application that I want to configure for multiuser use. The bokeh server is running on a AWS debian server. The normal bokeh server part works perfectly fine.

Now I tried to set up flask and gunicorn with the example of github [link]. When I copy the needed files to the debian server and start it with the gunicorn command, it shows that the gunicorn is starting and listening at https://localhost:8000. What I don’t understand is how I have to edit the flask_gunicorn_embed.py file that I can access the page from a different device (my notebook). If I open the IP with port (http://35.XXX.XXX.153:8000/). I just get “The website is not accessible”. This is how I edited the flask_gunicorn_embed.py file to try to make it work:

import asyncio
from threading import Thread
from flask import Flask, render_template
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.embed import server_document
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature
from bokeh.server.server import BaseServer
from bokeh.server.tornado import BokehTornado
from bokeh.server.util import bind_sockets
from bokeh.themes import Theme
if __name__ == '__main__':
    print('This script is intended to be run with gunicorn. e.g.')
    print('    gunicorn -w 4 flask_gunicorn_embed:app')
    print('will start the app on four processes')
    import sys
app = Flask(__name__)
def bkapp(doc):
    df = sea_surface_temperature.copy()
    source = ColumnDataSource(data=df)
    plot = figure(x_axis_type='datetime', y_range=(0, 25), y_axis_label='Temperature (Celsius)',
                  title="Sea Surface Temperature at 43.18, -70.43")
    plot.line('time', 'temperature', source=source)
    def callback(attr, old, new):
        if new == 0:
            data = df
            data = df.rolling(f"{new}D").mean()
        source.data = ColumnDataSource.from_df(data)
    slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
    slider.on_change('value', callback)
    doc.add_root(column(slider, plot))
    doc.theme = Theme(filename="theme.yaml")
# can't use shortcuts here, since we are passing to low level BokehTornado
bkapp = Application(FunctionHandler(bkapp))
# This is so that if this app is run using something like "gunicorn -w 4" then
# each process will listen on its own port
sockets, port = bind_sockets("localhost", 5006)
@app.route('/', methods=['GET'])
def bkapp_page():
    script = server_document('http://35.XXX.XXX.153:%d/bkapp' % port)
    return render_template("embed.html", script=script, template="Flask")
def bk_worker():
    bokeh_tornado = BokehTornado({'/bkapp': bkapp}, extra_websocket_origins=["", "localhost:8000", "35.XXX.XXX.153:8000", "", "localhost:5006", "35.XXX.XXX.153:5006"])
    bokeh_http = HTTPServer(bokeh_tornado)
    server = BaseServer(IOLoop.current(), bokeh_tornado, bokeh_http)

t = Thread(target=bk_worker)
t.daemon = True

I hope someone can help me. Thank you very much!

I got one step further. I edited the gunicorn command to
gunicorn3 -w 1 --bind flask_gunicorn_embed:app
and now I can access the page through http://35.XXX.XXX.153:8000/. But I just see the title from the embed.html page and not the plot. I get an error in the browser console:
:5006/bkapp/autoload.js?bokeh-autoload-element=1002&bokeh-app-path=/bkapp&bokeh-absolute-url=http://35.XXX.XXX.153:5006/bkapp:1 Failed to load resource: net::ERR_CONNECTION_TIMED_OUT

I am not sure how to fix that error.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.