starFire
starFire

Reputation: 117

Passing arguments to Bokeh autoload_server from Flask api

I started using Bokeh last week, so very much new to it, I am trying to create an interactive bar chart using sliders and dropdowns embedded in Flask API, so I created the flask api for the same, its showing the chart with a slider and dropdown but its not dynamically updating the chart upon changing the slider/dropdown value.

Then upon further research I found out that I need to have a separate bokeh server running for the interaction part and call the autoload server from my Flask api. But in that I am not sure how to send my http post params to the bokeh server as my input data is from an external API with params as user input.

script=autoload_server(model=None,app_path="/bokeh-sliders",url="http://localhost:5006")
return render_template('hello.html',script=script)

In reference to Sending URL parameter from Flask to a Bokeh server as I am not able to comment in it, it seems the feature has been integrated to pass arguments to the autoload server but I cant seem to find any documentation on it. Please help me in figuring this out.

On a side note, just to be sure, is it not possible to do interactions such as slider, dropdown, etc in just the flask api without running a bokeh server.

Thanks in advance.

Upvotes: 1

Views: 1105

Answers (1)

apfelbiene
apfelbiene

Reputation: 31

I was having the same problems, not being able to add interactions with Flask, and went down the same road. The issue of passing arguments is also discussed here.

The functionality has been added to Bokeh 0.12.7, and you can now pass a dictionary of key/values to include to the app script using the arguments parameter:

script = server_document("https://example.com/myapp",
                         arguments={'foo': 'bar'})

Note that server_document is a recently-added, simpler replacement for autoload_server


For versions before 0.12.7, you can also use the following workaround (credit goes to kevinsa5 on github):

@app.route('/amped')
def amped():
    script = autoload_server(model = None, app_path="/amped")
    # `script` is a string that looks like this (the first character is a newline):
    """
<script
    src="http://localhost:5006/amped/autoload.js?bokeh-autoload-element=6b813263-05df-45a5-bd91-e25c5e53c020"
    id="6b813263-05df-45a5-bd91-e25c5e53c020"
    data-bokeh-model-id=""
    data-bokeh-doc-id=""
></script>
"""
    # so to add on the necessary parameters, we have to insert them manually.  hopefully we won't need to urlencode anything.
    # note that request.args = a MultiDict, so be careful of duplicate params
    # http://werkzeug.pocoo.org/docs/0.11/datastructures/#werkzeug.datastructures.MultiDict

    script_list = script.split("\n")
    script_list[2] = script_list[2][:-1]
    for key in request.args:
        script_list[2] = script_list[2] + "&{}={}".format(key, request.args[key])
    script_list[2] = script_list[2] + '"'
    script = "\n".join(script_list)
    return render_template("amped.html", script = script)

This allows you to access it using

doc.session_context.request.arguments

Upvotes: 3

Related Questions