Cannot Load Script: Bokeh Embedded in Flask at Different Port from 5006

Hi,

I am developing a Bokeh-Embedded Flask app that needs to use a port other than 5006. As a minimum case, I modified the flask_embed.py example a bit (as attached below) to allow for using a different port, but the webpage cannot load the Bokeh plots if the port number is not 5006 - on the JS console it reads:

http://127.0.0.1:31051/bkapp/autoload.js?bokeh-autoload-element=4e079af1-8d05-497a-9ff0-71adb38aa39b Failed to load resource: net::ERR_CONNECTION_REFUSED

It seems that the Bokeh server refuses to connect the the Flask server when the port number is not 5006. Moreover, the returned script by autoload_server is embedded in the html with {{ script | safe}}. I feel the “safe” here may cause the problem, yet I’ve googling around but cannot solve the problem. Anyone kindly know how to deal with it?

Thanks,

Luyu

···

from flask import Flask, render_template

import numpy as np

from tornado.ioloop import IOLoop

from bokeh.application import Application

from bokeh.application.handlers import FunctionHandler

from bokeh.embed import autoload_server

from bokeh.layouts import column

from bokeh.models import ColumnDataSource, Slider

from bokeh.plotting import figure

from bokeh.server.server import Server

flask_app = Flask(name)

flask_host = “127.0.0.1:31050”

bokeh_host = “127.0.0.1:31051”

def modify_doc(doc):

x = np.linspace(0, 10, 1000)

y = np.log(x) * np.sin(x)

source = ColumnDataSource(data=dict(x=x, y=y))

plot = figure()

plot.line(‘x’, ‘y’, source=source)

slider = Slider(start=1, end=10, value=1, step=0.1)

def callback(attr, old, new):

y = np.log(x) * np.sin(x*new)

source.data = dict(x=x, y=y)

slider.on_change(‘value’, callback)

doc.add_root(column(slider, plot))

bokeh_app = Application(FunctionHandler(modify_doc))

io_loop = IOLoop.current()

server = Server({’/bkapp’: bokeh_app}, io_loop=io_loop, host=[bokeh_host], allow_websocket_origin=[flask_host, “127.0.0.1”])

server.start()

@flask_app.route(’/’, methods=[‘GET’])

def bkapp_page():

script = autoload_server(model=None, app_path=’/bkapp’, url=‘http://’+bokeh_host)

return render_template(“test.html”, script=script)

if name == ‘main’:

from tornado.httpserver import HTTPServer

from tornado.wsgi import WSGIContainer

from bokeh.util.browser import view

print(‘Opening Flask app with embedded Bokeh application on http://’+flask_host+’/’)

This uses Tornado to server the WSGI app that flask provides. Presumably the IOLoop

could also be started in a thread, and Flask could server its own app directly

http_server = HTTPServer(WSGIContainer(flask_app))

http_server.listen(address=flask_host.split(’:’)[0], port=flask_host.split(’:’)[1])

io_loop.add_callback(view, “http://”+flask_host+’/’)

io_loop.start()

Hi,

Server accepts a "port" argument that specifies what port the embedded server should listen, it does not look like you are setting it to be anything different than the default (which is 5006)?

Thanks,

Bryan

···

On Jan 26, 2017, at 4:37 PM, Luyu Wang <[email protected]> wrote:

Hi,

I am developing a Bokeh-Embedded Flask app that needs to use a port other than 5006. As a minimum case, I modified the flask_embed.py example a bit (as attached below) to allow for using a different port, but the webpage cannot load the Bokeh plots if the port number is not 5006 - on the JS console it reads:

http://127.0.0.1:31051/bkapp/autoload.js?bokeh-autoload-element=4e079af1-8d05-497a-9ff0-71adb38aa39b Failed to load resource: net::ERR_CONNECTION_REFUSED

It seems that the Bokeh server refuses to connect the the Flask server when the port number is not 5006. Moreover, the returned script by autoload_server is embedded in the html with {{ script | safe}}. I feel the "safe" here may cause the problem, yet I've googling around but cannot solve the problem. Anyone kindly know how to deal with it?

Thanks,
Luyu

-------------

from flask import Flask, render_template
import numpy as np
from tornado.ioloop import IOLoop

from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.embed import autoload_server
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Slider
from bokeh.plotting import figure
from bokeh.server.server import Server

flask_app = Flask(__name__)

flask_host = "127.0.0.1:31050"
bokeh_host = "127.0.0.1:31051"

def modify_doc(doc):
    x = np.linspace(0, 10, 1000)
    y = np.log(x) * np.sin(x)

    source = ColumnDataSource(data=dict(x=x, y=y))

    plot = figure()
    plot.line('x', 'y', source=source)

    slider = Slider(start=1, end=10, value=1, step=0.1)

    def callback(attr, old, new):
        y = np.log(x) * np.sin(x*new)
        source.data = dict(x=x, y=y)
    slider.on_change('value', callback)

    doc.add_root(column(slider, plot))

bokeh_app = Application(FunctionHandler(modify_doc))

io_loop = IOLoop.current()

server = Server({'/bkapp': bokeh_app}, io_loop=io_loop, host=[bokeh_host], allow_websocket_origin=[flask_host, "127.0.0.1"])
server.start()

@flask_app.route('/', methods=['GET'])
def bkapp_page():
    script = autoload_server(model=None, app_path='/bkapp', url='http://'+bokeh_host)
    return render_template("test.html", script=script)

if __name__ == '__main__':
    from tornado.httpserver import HTTPServer
    from tornado.wsgi import WSGIContainer
    from bokeh.util.browser import view

    print('Opening Flask app with embedded Bokeh application on http://‘+flask_host+’/')

    # This uses Tornado to server the WSGI app that flask provides. Presumably the IOLoop
    # could also be started in a thread, and Flask could server its own app directly
    http_server = HTTPServer(WSGIContainer(flask_app))
    http_server.listen(address=flask_host.split(':')[0], port=flask_host.split(':')[1])

    io_loop.add_callback(view, "http://"+flask_host+'/')
    io_loop.start()

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/5031023a-b335-42b7-bd86-f680627d7162%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Thank you Bryan for your help. I’ve solved the problem in the following way - I changed:

server = Server({‘/bkapp’: bokeh_app}, io_loop=io_loop, host=[bokeh_host], allow_websocket_origin=[flask_host, “127.0.0.1”])

server.start()

into

server = Server({‘/bkapp’: bokeh_app}, io_loop=io_loop, address=bokeh_host.split(‘:’)[0], port=int(bokeh_host.split(‘:’)[1]), allow_websocket_origin=[flask_host])

In summary, using ‘address’ and ‘port’ arguments to specify the bokeh server instead of using ‘host’ (in the format of “ip:port”) solves the problem.

···

On Thursday, January 26, 2017 at 5:49:59 PM UTC-5, Bryan Van de ven wrote:

Hi,

Server accepts a “port” argument that specifies what port the embedded server should listen, it does not look like you are setting it to be anything different than the default (which is 5006)?

Thanks,

Bryan

On Jan 26, 2017, at 4:37 PM, Luyu Wang [email protected] wrote:

Hi,

I am developing a Bokeh-Embedded Flask app that needs to use a port other than 5006. As a minimum case, I modified the flask_embed.py example a bit (as attached below) to allow for using a different port, but the webpage cannot load the Bokeh plots if the port number is not 5006 - on the JS console it reads:

http://127.0.0.1:31051/bkapp/autoload.js?bokeh-autoload-element=4e079af1-8d05-497a-9ff0-71adb38aa39b Failed to load resource: net::ERR_CONNECTION_REFUSED

It seems that the Bokeh server refuses to connect the the Flask server when the port number is not 5006. Moreover, the returned script by autoload_server is embedded in the html with {{ script | safe}}. I feel the “safe” here may cause the problem, yet I’ve googling around but cannot solve the problem. Anyone kindly know how to deal with it?

Thanks,

Luyu


from flask import Flask, render_template

import numpy as np

from tornado.ioloop import IOLoop

from bokeh.application import Application

from bokeh.application.handlers import FunctionHandler

from bokeh.embed import autoload_server

from bokeh.layouts import column

from bokeh.models import ColumnDataSource, Slider

from bokeh.plotting import figure

from bokeh.server.server import Server

flask_app = Flask(name)

flask_host = “127.0.0.1:31050

bokeh_host = “127.0.0.1:31051

def modify_doc(doc):

x = np.linspace(0, 10, 1000)
y = np.log(x) * np.sin(x)
source = ColumnDataSource(data=dict(x=x, y=y))
plot = figure()
plot.line('x', 'y', source=source)
slider = Slider(start=1, end=10, value=1, step=0.1)
def callback(attr, old, new):
    y = np.log(x) * np.sin(x*new)
    source.data = dict(x=x, y=y)
slider.on_change('value', callback)
doc.add_root(column(slider, plot))

bokeh_app = Application(FunctionHandler(modify_doc))

io_loop = IOLoop.current()

server = Server({‘/bkapp’: bokeh_app}, io_loop=io_loop, host=[bokeh_host], allow_websocket_origin=[flask_host, “127.0.0.1”])

server.start()

@flask_app.route(‘/’, methods=[‘GET’])

def bkapp_page():

script = autoload_server(model=None, app_path='/bkapp', url='http://'+bokeh_host)
return render_template("test.html", script=script)

if name == ‘main’:

from tornado.httpserver import HTTPServer
from tornado.wsgi import WSGIContainer
from bokeh.util.browser import view
print('Opening Flask app with embedded Bokeh application on http://'+flask_host+'/')
# This uses Tornado to server the WSGI app that flask provides. Presumably the IOLoop
# could also be started in a thread, and Flask could server its own app directly
http_server = HTTPServer(WSGIContainer(flask_app))
http_server.listen(address=flask_host.split(':')[0], port=flask_host.split(':')[1])
io_loop.add_callback(view, "http://"+flask_host+'/')
io_loop.start()


You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/5031023a-b335-42b7-bd86-f680627d7162%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Right, there seems to be general confusion, but the `host` argument is not to tell the bokeh server where to run or listen or anything like that. The host argument states what values in HTTP connection headers are allowable. If someone tries to connect and the HOST field of the HTTP request is not in the Bokeh server hosts whitelist, it will be rejected. This is to prevent various attacks based on spoofed HTTP headers, especially when running bokeh server behind a proxy.

Thanks,

Bryan

···

On Jan 26, 2017, at 5:58 PM, Luyu Wang <[email protected]> wrote:

Thank you Bryan for your help. I've solved the problem in the following way - I changed:

server = Server({'/bkapp': bokeh_app}, io_loop=io_loop, host=[bokeh_host], allow_websocket_origin=[flask_host, "127.0.0.1"])
server.start()

into

server = Server({'/bkapp': bokeh_app}, io_loop=io_loop, address=bokeh_host.split(':')[0], port=int(bokeh_host.split(':')[1]), allow_websocket_origin=[flask_host])

In summary, using 'address' and 'port' arguments to specify the bokeh server instead of using 'host' (in the format of "ip:port") solves the problem.

On Thursday, January 26, 2017 at 5:49:59 PM UTC-5, Bryan Van de ven wrote:
Hi,

Server accepts a "port" argument that specifies what port the embedded server should listen, it does not look like you are setting it to be anything different than the default (which is 5006)?

Thanks,

Bryan

> On Jan 26, 2017, at 4:37 PM, Luyu Wang <[email protected]> wrote:
>
> Hi,
>
> I am developing a Bokeh-Embedded Flask app that needs to use a port other than 5006. As a minimum case, I modified the flask_embed.py example a bit (as attached below) to allow for using a different port, but the webpage cannot load the Bokeh plots if the port number is not 5006 - on the JS console it reads:
>
> http://127.0.0.1:31051/bkapp/autoload.js?bokeh-autoload-element=4e079af1-8d05-497a-9ff0-71adb38aa39b Failed to load resource: net::ERR_CONNECTION_REFUSED
>
> It seems that the Bokeh server refuses to connect the the Flask server when the port number is not 5006. Moreover, the returned script by autoload_server is embedded in the html with {{ script | safe}}. I feel the "safe" here may cause the problem, yet I've googling around but cannot solve the problem. Anyone kindly know how to deal with it?
>
> Thanks,
> Luyu
>
> -------------
>
> from flask import Flask, render_template
> import numpy as np
> from tornado.ioloop import IOLoop
>
> from bokeh.application import Application
> from bokeh.application.handlers import FunctionHandler
> from bokeh.embed import autoload_server
> from bokeh.layouts import column
> from bokeh.models import ColumnDataSource, Slider
> from bokeh.plotting import figure
> from bokeh.server.server import Server
>
> flask_app = Flask(__name__)
>
> flask_host = "127.0.0.1:31050"
> bokeh_host = "127.0.0.1:31051"
>
> def modify_doc(doc):
> x = np.linspace(0, 10, 1000)
> y = np.log(x) * np.sin(x)
>
> source = ColumnDataSource(data=dict(x=x, y=y))
>
> plot = figure()
> plot.line('x', 'y', source=source)
>
> slider = Slider(start=1, end=10, value=1, step=0.1)
>
> def callback(attr, old, new):
> y = np.log(x) * np.sin(x*new)
> source.data = dict(x=x, y=y)
> slider.on_change('value', callback)
>
> doc.add_root(column(slider, plot))
>
> bokeh_app = Application(FunctionHandler(modify_doc))
>
> io_loop = IOLoop.current()
>
> server = Server({'/bkapp': bokeh_app}, io_loop=io_loop, host=[bokeh_host], allow_websocket_origin=[flask_host, "127.0.0.1"])
> server.start()
>
> @flask_app.route('/', methods=['GET'])
> def bkapp_page():
> script = autoload_server(model=None, app_path='/bkapp', url='http://‘+bokeh_host)
> return render_template("test.html", script=script)
>
> if __name__ == '__main__':
> from tornado.httpserver import HTTPServer
> from tornado.wsgi import WSGIContainer
> from bokeh.util.browser import view
>
> print('Opening Flask app with embedded Bokeh application on http://’+flask_host+‘/')
>
> # This uses Tornado to server the WSGI app that flask provides. Presumably the IOLoop
> # could also be started in a thread, and Flask could server its own app directly
> http_server = HTTPServer(WSGIContainer(flask_app))
> http_server.listen(address=flask_host.split(':')[0], port=flask_host.split(':')[1])
>
> io_loop.add_callback(view, "http://"+flask_host+’/')
> io_loop.start()
>
> --
> You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+un...@continuum.io.
> To post to this group, send email to bo...@continuum.io.
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/5031023a-b335-42b7-bd86-f680627d7162%40continuum.io\.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/0ce76269-95a1-4ca4-af73-2140b43862a9%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.