Bokeh Session started with on a Flask server

I have a function modify_doc which returns a curdoc() session.

def modify_doc(document_session):

     ...code...

    return document_session.add_root(layout)

It mostly working as expected, but wrapping it in Flask app.py has proven to be more difficult and I could use some feedback. My initial approach is to start a bokeh server on “/bokeh” and then the flask app picks it up on “/dashboard” from my understanding.

from flask import Flask, render_template
from bokeh.embed import server_document
from bokeh.server.server import Server
from dashboard import modify_doc
from tornado.ioloop import IOLoop

application = Flask(__name__)

@application.route("/dashboard")
def server():
	tag = server_document(url=r'/bokeh', relative_urls=True)
	return render_template('index.html', tag=tag)

def worker():
	server = Server(
		modify_doc, 
		prefix=r'/bokeh', 
		io_loop=IOLoop(), 
		allow_websocket_origin= ["localhost:5006"])
	server.start()
	server.io_loop.start()

from threading import Thread
Thread(target=worker).start()

if __name__ == "__main__":
	application.run(port=5006, debug=True)

However, the servers start with python app.py mostly fine, but the bokeh server gives an error “GET http://localhost:5000/bokeh/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bokeh net::ERR_ABORTED 404 (NOT FOUND)” and traceback from terminal:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 926, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/bb/Documents/External Drive/19-10-25 preliminary project materials/source/app.py", line 23, in worker
    allow_websocket_origin= ["localhost:5006"])
  File "/Users/bb/Documents/External Drive/19-10-25 preliminary project materials/source/vm/lib/python3.7/site-packages/bokeh/server/server.py", line 393, in __init__
    sockets, self._port = bind_sockets(self.address, self.port)
  File "/Users/bb/Documents/External Drive/19-10-25 preliminary project materials/source/vm/lib/python3.7/site-packages/bokeh/server/util.py", line 66, in bind_sockets
    ss = netutil.bind_sockets(port=port or 0, address=address)
  File "/Users/bb/Documents/External Drive/19-10-25 preliminary project materials/source/vm/lib/python3.7/site-packages/tornado/netutil.py", line 174, in bind_sockets
    sock.bind(sockaddr)
OSError: [Errno 48] Address already in use

You are starting the Flask application on the same port at the Bokeh server (5006). They have to be on different ports.

if __name__ == "__main__":
    	application.run(port=5000, debug=True)

Sorry for the confusion. I had tried the above configuration previously, tried distinguishing the ports, as a method of troubleshooting, but it resulted in the same below error.

OSError: [Errno 48] Address already in use

Suspiciously, even with a fresh restart to make sure nothing is blocking any ports, it still returns the error above. Something about the Bokeh server is not making it to the Flask server. I decided I needed expertise because I thought this might have something subtle to do about how I sequenced starting the the servers or something? It’s all a bit mysterious to me. Is there a deeper way to check port 5000? I’m only getting normal errors when I direct a chrome window there. No file structure or anything. I think I’ve confirmed there isn’t anything running on these ports which only leaves vague answers left.

Here’s a related error from the JS Console:

GET http://localhost:5000/bokeh/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bokeh&bokeh-absolute-url=/bokeh net::ERR_ABORTED 404 (NOT FOUND)

If I simply things a I can now see the bokeh server work normally on port 5000, but what does this JS error mean on /dashbaord?

That sounds like you have a linger Bokeh server process running somewhere, e.g in another terminal? Alternatively you have something else on port 5000 already running on the system. The prohibition against re-using ports is an OS constraint, not something specifically to do with Bokeh. If you are on a *nix system you can look in to the netstat commands which will show what ports are currently in use.

GET http://localhost:5000/bokeh/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bokeh&bokeh-absolute-url=/bokeh net::ERR_ABORTED 404 (NOT FOUND)

I don’t understand why the bokeh server is at port 5000 now? If you left it alone and only changed the Flask port, then it would be at 5006 (the default).

Hi there,

I have ran into similar issue - I am starting thread with Bokeh server from my flask app and similar error appears every time (Address already in use), even though I have specifically set different ports for those two apps. However, the Bokeh server still works and I can pull data from Bokeh Server into my Flask views without problems. My guess is that flask (or something else) is trying to run the code for bokeh server twice and it’s the second time that raises an error as the server is already running. Perhaps you can try and see if that works for you as well?

Hi all and future me,

@BBirdsell I ran into the same problem and could not figure out how to make it work using the bokeh.server command. I am aware of the age of this post. Hopefully it will provide some insides for others.
Anyway I found an example in the bokeh repo that solves a similar problem. It is maybe not elegant and i am looking forward to discuss the approach.
bokeh server session example

If you don’t want to run two commands in two consoles you can try adding a subpocess to the serve.py
like this e.g.

subprocess.Popen(["bokeh", "serve", "--port", "5100", "--allow-websocket-origin", "localhost:8080", "--allow-websocket-origin", "127.0.0.1:8080", "bokeh_app.py"])

That way you will get a python flask app that calls bokeh serve in the background.

Best regards lambdify