Call Bokeh Server App Python Function from Javascript

I am searching for a way to call a python function of my Bokeh Server App from arbitrary Javascript. I want to write custom widgets using HTML/Javascript only and use them to interact with the Bokeh App. I know that one can extend bokeh. Is this is the only way to go? For fast prototyping and for greater flexibility with respect to used UI frameworks I think it would be nice to just use the websocket connection to send requests to the app, something along this line:

Bokeh.doc.call(‘my_python_func’, arg1, arg2)

``

Is this really not an issue? I want to embed an autoload bokeh app within a vuejs application and use vuejs based widgets to control the plot. If this is not something you want to support within bokeh, please let me know why. If you do, but don’t have the time to implement this, it would be great if you could give me a hint where to start in bokehj, so I could eventually make a PR. For me it looks like a much more generic way to add custom widgets, don’t you think?

···

Am Dienstag, 31. Januar 2017 14:52:22 UTC+1 schrieb [email protected]:

I am searching for a way to call a python function of my Bokeh Server App from arbitrary Javascript. I want to write custom widgets using HTML/Javascript only and use them to interact with the Bokeh App. I know that one can extend bokeh. Is this is the only way to go? For fast prototyping and for greater flexibility with respect to used UI frameworks I think it would be nice to just use the websocket connection to send requests to the app, something along this line:

Bokeh.doc.call(‘my_python_func’, arg1, arg2)

``

Hi,

There is a an open issue to cover this feature:

  Events with feedback / Simple RPC · Issue #5983 · bokeh/bokeh · GitHub

It is currently scheduled for the 0.12.8 milestone. I had hoped it could be in the next release but there is simply not enough available developer time to get everything done by then given other important priorities.

If you are interested in working on this, I would not want to discourage you, but I would also want to be up front and say that this will not be a trivial undertaking. It will required Python and BokehJS work, and additions at the protocol level, so will need to come with extensive tests. There is also a wide spectrum between "toy RPC" and "bulletproof RPC" (e.g. CORBA), so there needs to be thought about just how comprehensive Bokeh will actually able to be, and thorough documentation with discussion of any limitations or compromises.

If you are still interested in starting a PR, let me know and I will write up some more detailed guidance to get you started.

Thanks,

Bryan

···

On Aug 8, 2017, at 09:53, [email protected] wrote:

Is this really not an issue? I want to embed an autoload bokeh app within a vuejs application and use vuejs based widgets to control the plot. If this is not something you want to support within bokeh, please let me know why. If you do, but don't have the time to implement this, it would be great if you could give me a hint where to start in bokehj, so I could eventually make a PR. For me it looks like a much more generic way to add custom widgets, don't you think?

Am Dienstag, 31. Januar 2017 14:52:22 UTC+1 schrieb alexand...@gmail.com:
I am searching for a way to call a python function of my Bokeh Server App from arbitrary Javascript. I want to write custom widgets using HTML/Javascript only and use them to interact with the Bokeh App. I know that one can extend bokeh. Is this is the only way to go? For fast prototyping and for greater flexibility with respect to used UI frameworks I think it would be nice to just use the websocket connection to send requests to the app, something along this line:

Bokeh.doc.call('my_python_func', arg1, arg2)

--
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/7448cd85-59cf-4a0f-ba25-9444189df924%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Dear Bryan,

I am struggling online since two days to find a way to do what alexander.koehn asked you.

Have been this feature implemented ? Is there any documentation ?

Thank you very much,
Paolo

@PaoloFranzetti This feature has not been implemented (it is still an open issue). I am not sure when it might gotten too. A kludgy workaround is for now is to do something like: add an invisible glyph to the plot, and attach an on_change callback to some property of that glyph. Then you can trigger the callback by changing the property’s value.

@Bryan Thank you for your answer. The solution you proposed is exactly what I tried to do, but it does not work, at least in my implementation. These are my test scripts (main.py and index.html); am I doing something wrong ?

Paolo

from bokeh.plotting import figure, curdoc

from bokeh.models import ColumnDataSource


y = range(100)
x = range(100)


def callback(attrname, old, new):

	print ('I AM HERE')


print ('I CAN PRINT')

source = ColumnDataSource(data=dict(x=x, y=y))
coords = ColumnDataSource(data=dict(x=(1,), y=(1,)), name='coords')
coords.on_change('data', callback)

plot = figure(plot_height=400, plot_width=1000, title="1 1",
              tools="crosshair,pan,reset,save,wheel_zoom",name="spec")

plot.line('x', 'y', source=source, line_width=1, line_alpha=1)
plot.line('x', 'y', source=coords, line_width=0, line_alpha=1)

curdoc().add_root(plot)

.

{% extends base %}

<!-- goes in head -->
{% block preamble %}


<script type="text/javascript">
<!--


function test()
{
  
  var ds = Bokeh.documents[0].get_model_by_name('coords');
  ds.data['x'][0] = 1000;
  ds.data['y'][0] = 1000;
  ds.change.emit();
  
  
}

//-->
</script>


{% endblock %}

<!-- goes in body -->
{% block contents %}


<input type="button" value="click me" onclick="test()" />


<div id="plot"> {{ embed(roots.spec) }} </div>

{% endblock %}

@PaoloFranzetti The machinery for auto-synchronization between Python and JS only triggers when there are actual assignments that are made. You will need to actually assign to .data even if it is just

ds.data = data

at the end (The emit call should be unnecessary)

OK, now it works smoothly.

Thank you very much for your help!

1 Like