Question

Python bokeh with flask and gunicorn err_connection_refused

Hi everyone,

I am trying to set up an bokeh application with flask and gunicorn. I am working on a debian system on an AWS server with the IP 35.XXX.XXX.153. I used the example from git and edited it in the way that I think it should work. The problem is, when I run the gunicorn command (gunicorn3 -w 1 --bind 0.0.0.0:8000 wsgi:app) I get an error in the browser terminal:

(index):30 GET http:// 35.XXX.XXX.153:5006/bkapp/autoload.js?bokeh-autoload-element=4755&bokeh-app-path=/bkapp&bokeh-absolute-url=http:// 35.XXX.XXX.153:5006/bkapp net::ERR_CONNECTION_REFUSED

I have no clue why I get a ERR_CONNECTION_REFUSED.

Here is my code: flaskapp.py

import asyncio

from threading import Thread

from flask import Flask, render_template
from flask_cors import CORS
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop

from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.client import pull_session
from bokeh.core.validation import silence
from bokeh.core.validation.warnings import FIXED_SIZING_MODE
from bokeh.embed import server_document, autoload_static, server_session
from bokeh.io import curdoc
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 Server
from bokeh.server.server import BaseServer
from bokeh.server.tornado import BokehTornado
from bokeh.server.util import bind_sockets
from bokeh.themes import Theme

import data.DataHead as DataHead

if __name__ == '__main__':
    print('This script is intended to be run with gunicorn. e.g.')
    print()
    print('    gunicorn -w 4 flask_gunicorn_embed:app')
    print()
    print('will start the app on four processes')
    import sys
    sys.exit()


app = Flask(__name__)
CORS(app)

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
        else:
            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")
        
bkapp = Application(FunctionHandler(bkapp))

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():
    asyncio.set_event_loop(asyncio.new_event_loop())
    bokeh_tornado = BokehTornado({'/bkapp': bkapp}, extra_websocket_origins=["*"])
    bokeh_http = HTTPServer(bokeh_tornado)
    bokeh_http.add_sockets(sockets)

    server = BaseServer(IOLoop.current(), bokeh_tornado, bokeh_http)
    server.start()
    server.io_loop.start()

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

wsgi.py

from flaskapp import app

if __name__ == "__main__":
    app.run()

embed.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    {{ bokeh_css }}
    {{ bokeh_js }}
    <link rel="stylesheet" href="./static/css/styles.css" type="text/css"/>
    <link rel="shortcut icon" href="./static/favicon/favicon.ico" type="image/x-icon">
  </head>
  <body>
    <div class="head">
        <a href="http://"><img src="./static/images/logo.png" width="93px" height="36px"/></a>
     </div>
    <div class="body">
      {{ script|safe }}
    </div>
  </body>
</html>

On the debian server I forwarded the ports 80, 443, 5006-5015, 5432, 8000, 8080.

Maybe someone has an idea why I am getting this error and how I can resolve it. Thank you!


Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in Q&A, subscribe to topics of interest, and get courses and tools that will help you grow as a developer and scale your project or business.

Hi there,

Your Flask app is binding on localhost:

bind_sockets("localhost", 5006)

This means that you will only be able to access the service locally and not from any external source.

What you could do is use 0.0.0.0 instead of localhost, that way the service will be exposed to the world and you will be able to access it on port 5006.

Hope that this helps!

Best,

Bobby