I am trying to embed a Bokeh server in a Flask application, but I keep getting the error “OSError: [Errno 98] Address already in use”
Now I know for a fact that before I enter “flask run” on the command line, there are no other processes running on the default Bokeh server port (5006), because I kill any hanging processes using lsof -i and then kill -9 PID.
I suspect that it has something to do with flask attempting to execute the bk_worker function multiple times, each with the same port.
When I execute my plot python script using “bokeh serve plot.py” from the command line, it runs fine, and I can access the plot at http://localhost:5006/plot. However, when I try to execute from within the Flask app, I get the OSError.
This is the code I have executing in init.py. I have tried using both the Bokeh-recommended method of using Thread, as well as just calling bk_worker directly since Flask does some multiprocessing stuff as well. Either way, I receive the same OSError for the port already being in use.
init.py
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
def bk_worker():
server = Server({'/plot': plot}, io_loop=IOLoop(), allow_websocket_origin=["localhost:{}".format(5000)])
server.start()
server.io_loop.start()
#from threading import Thread
#Thread(target=bk_worker).start()
bk_worker()
This is the code I am using from within my application’s routes.py to get the bokeh plot, which I then pass to the html render.
routes.py
@app.route('/bokeh_plot', methods=['GET', 'POST'])
def bokeh_plot():
script = server_document('http://localhost:5006/plot')
return render_template('bokeh_plot.html', script=script)
The plot itself that I am linking the server to is in a file called plot.py with the following format. I know this code works, because I can serve it using the bokeh serve command
plot.py
def plot(doc):
...code to make plot...
return plot
My first thought is that I am not running the bk_worker function in the correct Flask file? Or I am not understanding something about the way my ports are configured? Most of the examples I see have the entire application running in a single file, but my application is a little more complex, so I have the bk_worker function executing in my init.py. I have also tried putting it in routes.py under the ‘/plot’ route that calls it. My file layout structure is generally the same as in the Flask Mega Tutorial
Environment:
I am developing in Windows Subsystem for Linux with Ubuntu 20.04 LTS.
Python Version: 3.6.10
Bokeh Version: 2.3.0
Flask Version: 1.1.2