Ying Wang
Ying Wang

Reputation: 57

Error in embedding bokeh serve in flask by using flask_embed.py

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

Answers (1)

bigreddot
bigreddot

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

Related Questions