Reputation: 57
I would like to embed bokeh serve into flask framework. Thus, I used a piece of code from online called "flask_embed.py", the code and corresponding HTML is attached as follow. However, I got errors after running it. Anyone had this issue before?
The errors are:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\ProgramData\Anaconda3\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "flaskBokehHighchart.py", line 44, in bk_worker
server = Server({'/bkapp': modify_doc}, allow_websocket_origin=["localhost:5000"])
File "C:\ProgramData\Anaconda3\lib\site-packages\bokeh\server\server.py", line 390, in __init__
sockets, self._port = bind_sockets(self.address, self.port)
File "C:\ProgramData\Anaconda3\lib\site-packages\bokeh\server\util.py", line 32, in bind_sockets
ss = netutil.bind_sockets(port=port or 0, address=address)
File "C:\ProgramData\Anaconda3\lib\site-packages\tornado\netutil.py", line 197, in bind_sockets
sock.bind(sockaddr)
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
''' Python code with flask:
from flask import Flask, render_template
from bokeh.embed import server_document
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
from bokeh.server.server import Server
from bokeh.themes import Theme
from bokeh.sampledata.sea_surface_temperature import sea_surface_temperature
app = Flask(__name__)
def modify_doc(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('{0}D'.format(new)).mean()
source.data = ColumnDataSource(data=data).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")
@app.route('/', methods=['GET'])
def bkapp_page():
script = server_document('http://localhost:5006/bkapp')
return render_template("embed.html", script=script, template="Flask")
def bk_worker():
# Can't pass num_procs > 1 in this configuration. If you need to run multiple
# processes, see e.g. flask_gunicorn_embed.py
server = Server({'/bkapp': modify_doc}, allow_websocket_origin=["localhost:8000"])
server.start()
server.io_loop.start()
from threading import Thread
Thread(target=bk_worker).start()
if __name__ == '__main__':
print('Opening single process Flask app with embedded Bokeh application on http://localhost:8000/')
print()
print('Multiple connections may block the Bokeh app in this configuration!')
print('See "flask_gunicorn_embed.py" for one way to run multi-process')
app.run(port=8000)
'''
HTML in templates named "embed.html":
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>App</title>
</head>
<body>
<div>HERE IS SOME CUSTOM STUFF</div>
{{ script|safe }}
</body>
</html>
Upvotes: 0
Views: 686
Reputation: 34568
Some other process on your system is already using port 5006. The most likely explanation is that you already have another Bokeh server running in another window. You can make sure other Bokeh server instances are shut down, or you could change the example code above to use a different port. You'd want to change the server_document
line, e.g.:
script = server_document('http://localhost:9090/bkapp')
Then also change the Server
line to use that same new port:
server = Server({'/bkapp': modify_doc}, allow_websocket_origin=["localhost:8000"],
# add this argument:
port=9090)
Upvotes: 1