widget "on_change" callback not working

Hello all,

I am trying to connect a simulator output stream to Bokeh. I am creating a server as mentioned at this link.

class TopClass (TopBlock):
def init(self, doc):
self.doc = doc
# Two constructors that create a plot and many plot specific things like ColumnDataSource and all.
# Also added a **doc.periodic_callback **during **initialisation **of the plot which gets data from simulator and
# send to Plot at every 10 ms.
self.plot1 = plot1(range1, frequency1)
self.plot2 = plot2(range2, frequency2)

self.textInput = TextInput(value="value", title="Yaxis")
self.textInput.on_change('value', self.print)

self.doc.add_root(column(self.textInput, self.plot1.plot, self.plot2.plot)) # self.plot1.plot is the correct Bokeh model

def print(self,attr,old,new):
print new

def main(top_block_cls=top_block, options=None):

Define tornado loop

loop = IOLoop()

Define a blank application

app = Application()

Starting server at port 5006

srv = Server({’/’:app},io_loop=loop)

Start server process

srv.start()

Define the document instance

doc = curdoc()

session = push_session(doc, session_id=“test”, io_loop=loop, url=‘http://localhost:5006/’)

Create Top Block instance

tb = top_block_cls(doc)

Start simulations as soon as the server starts

loop.add_callback(tb.start)
loop.add_callback(srv.show,’/?bokeh-session-id=’+str(session.id))
try:
loop.start()
except KeyboardInterrupt:
print “Exiting the simulation. Stopping Bokeh Server”
except Exception as e:
print str(e)
finally:
# Stop the simulations when there is a key interrupt
tb.stop()
tb.wait()

``

``

Again, the issue is: TextInput on_change callback is never triggered. I am using Bokeh 0.12.6, Tornado 4.4, Ubuntu GNOME 16.04.

I found this issue most relevant. But the solution can not be implemented as suggested there.

Some points to note:

  1. This is a bokeh server application. On various possible solutions, they mentioned using non-server application. Can’t do it in my case.

  2. The callback function should be pure Python function. I can not make it a CustomJS. The application shown here is basic.

  3. Please check the Application() and procedure of Server.start. Is this issue can be because of that?

  4. I can see the TextBox value updated in all open instances of the document. That means the update is being spread via the server to all connected clients.

Thank you for your help. Let me know if any further information is needed.

Hi,

Without a complete example that can be run actually run and debugged, it's hard to speculate what the usage problem might be. I can only say in general that offhand this code seems fairly different from any of the methods that are demonstrated in the docs or the GH examples repo. In case it is useful, here is a "standalone app embed" example that is tested with every release. Hopefully comparing it to your code, or using it as a starting point, will be useful:

  https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py

Thanks,

Bryan

···

On Jul 11, 2017, at 14:24, Kartik Patel <[email protected]> wrote:

Hello all,

I am trying to connect a simulator output stream to Bokeh. I am creating a server as mentioned at this link.

class TopClass (TopBlock):
  def __init__(self, doc):
    self.doc = doc

    # Two constructors that create a plot and many plot specific things like ColumnDataSource and all.
    # Also added a doc.periodic_callback during initialisation of the plot which gets data from simulator and
    # send to Plot at every 10 ms.
    self.plot1 = plot1(range1, frequency1)
    self.plot2 = plot2(range2, frequency2)

    self.textInput = TextInput(value="value", title="Yaxis")
    self.textInput.on_change('value', self.print)
    
    self.doc.add_root(column(self.textInput, self.plot1.plot, self.plot2.plot)) # self.plot1.plot is the correct Bokeh model

  def print(self,attr,old,new):
    print new

def main(top_block_cls=top_block, options=None):
  # Define tornado loop
  loop = IOLoop()
  # Define a blank application
  app = Application()
  # Starting server at port 5006
  srv = Server({'/':app},io_loop=loop)
  # Start server process
  srv.start()
  # Define the document instance
  doc = curdoc()

  session = push_session(doc, session_id="test", io_loop=loop, url='http://localhost:5006/')
  # Create Top Block instance
  tb = top_block_cls(doc)
  # Start simulations as soon as the server starts
  loop.add_callback(tb.start)
  loop.add_callback(srv.show,'/?bokeh-session-id='+str(session.id))
  try:
      loop.start()
  except KeyboardInterrupt:
      print "Exiting the simulation. Stopping Bokeh Server"
  except Exception as e:
      print str(e)
  finally:
      # Stop the simulations when there is a key interrupt
      tb.stop()
      tb.wait()

Again, the issue is: TextInput `on_change` callback is never triggered. I am using Bokeh 0.12.6, Tornado 4.4, Ubuntu GNOME 16.04.
I found this issue most relevant. But the solution can not be implemented as suggested there.

Some points to note:
1. This is a bokeh server application. On various possible solutions, they mentioned using non-server application. Can't do it in my case.
2. The callback function should be pure Python function. I can not make it a CustomJS. The application shown here is basic.
3. Please check the `Application()` and procedure of `Server.start`. Is this issue can be because of that?
4. I can see the TextBox value updated in all open instances of the document. That means the update is being spread via the server to all connected clients.

Thank you for your help. Let me know if any further information is needed.

--
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/c8a48f21-a8ee-47b6-8c3f-5bb6472f5dcc%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Dear Bryan,

Thank you for the quick update. I have created a sample file to show the issue. I have attached it to this message. The motivation of the design (from the start of my project) is the file you have suggested.

Now, if you see in my given code, the following things can be noted:

  1. The major difference between from the conventional way is probably creating a blank Application. Maybe textbox can not fire trigger because of that? Kindly check the server.start procedure. Is that a problem? If that is a problem, can you suggest a good way of doing things given the Temp() class structure remains mostly same except I can add some statements here and there? If it is not a problem, then would you suggest what can be a possible problem?

  2. The update_data is equivalent to my simulator streaming.

  3. I can see the TextBox value updated in all open instances of the document. That means the update is being spread via the server to all connected clients.

  4. Overall, I can have only one Python script that runs to display the plot. I should have only one Document per session, one session per app (to allow the results to be viewed from multiple systems), 1 app per Python script, one Python script execution at a time in a particular system.

Kindly let me know if you need further information. Any pointers to the issue will also be appreciated.

Thank you very much.

– Kartik

bokeh_on_change_debug.py (2.43 KB)

···

On Wednesday, July 12, 2017 at 1:07:45 AM UTC+5:30, Bryan Van de ven wrote:

Hi,

Without a complete example that can be run actually run and debugged, it’s hard to speculate what the usage problem might be. I can only say in general that offhand this code seems fairly different from any of the methods that are demonstrated in the docs or the GH examples repo. In case it is useful, here is a “standalone app embed” example that is tested with every release. Hopefully comparing it to your code, or using it as a starting point, will be useful:

    [https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py](https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py)

Thanks,

Bryan

Kartik,

My guess is that it has something to do with your creating a document and session by hand. Is there some specific reason you are doing this, instead of adding e.g. a FunctionHandler to the application, and letting the normal server app machinery create sessions and documents to service? "push_session" is typically only used in conjunction
with "bokeh.client" when there is a *separate* python process that remains connected outside the bokeh server. But that's not the case here, you are sort-of kind-of trying to split the difference between both approaches, and I am not sure that can be expected to work. I suspect the process that would handle the callback is blocking, in the configuration you are trying to set up.

But it will take investigation, when time and resources permit, so in the mean time I can only suggest creating a GitHub issue with this information, and emulating the working example I linked more closely. (i.e. use and app with a doc handler configured and don't push sessions by hand)

Bryan

···

On Jul 12, 2017, at 15:25, Kartik Patel <[email protected]> wrote:

Dear Bryan,

Thank you for the quick update. I have created a sample file to show the issue. I have attached it to this message. The motivation of the design (from the start of my project) is the file you have suggested.

Now, if you see in my given code, the following things can be noted:
1. The major difference between from the conventional way is probably creating a blank Application. Maybe textbox can not fire trigger because of that? Kindly check the server.start procedure. Is that a problem? If that is a problem, can you suggest a good way of doing things given the Temp() class structure remains mostly same except I can add some statements here and there? If it is not a problem, then would you suggest what can be a possible problem?
2. The update_data is equivalent to my simulator streaming.
3. I can see the TextBox value updated in all open instances of the document. That means the update is being spread via the server to all connected clients.
4. Overall, I can have only one Python script that runs to display the plot. I should have only one Document per session, one session per app (to allow the results to be viewed from multiple systems), 1 app per Python script, one Python script execution at a time in a particular system.

Kindly let me know if you need further information. Any pointers to the issue will also be appreciated.

Thank you very much.

-- Kartik

On Wednesday, July 12, 2017 at 1:07:45 AM UTC+5:30, Bryan Van de ven wrote:
Hi,

Without a complete example that can be run actually run and debugged, it's hard to speculate what the usage problem might be. I can only say in general that offhand this code seems fairly different from any of the methods that are demonstrated in the docs or the GH examples repo. In case it is useful, here is a "standalone app embed" example that is tested with every release. Hopefully comparing it to your code, or using it as a starting point, will be useful:

        https://github.com/bokeh/bokeh/blob/master/examples/howto/server_embed/standalone_embed.py

Thanks,

Bryan

--
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/2ee141b4-75cd-4b3d-a401-4b4500dea312%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.
<bokeh_on_change_debug.py>

Dear Bryan,

Thanks for the response.

My guess is that it has something to do with your creating a document and session by hand. Is there some specific reason you are doing this, instead of adding e.g. a FunctionHandler to the application, and letting the normal server app machinery create sessions and documents to service?
First of all, I can’t have more than one Document instance per Server. I want the server to run and then start the streaming data. I can’t have more than one Document instance because if I change a parameter of simulation from one client, I can’t run the separate program for other Document instance on another client. Now, to keep a common session and hence, common document, I must have known session (identified by sessionID) and corresponding Document. As far as I understand, a normal typical Server process will create separate sessions, hence, separate Documents.

“push_session” is typically only used in conjunction with “bokeh.client” when there is a separate python process that remains connected outside the bokeh server. But that’s not the case here, you are trying to split the difference between both approaches, and I am not sure that can be expected to work. I suspect the process that would handle the callback is blocking, in the configuration you are trying to set up.

I m afraid I don’t understand what do you mean by “splitting the difference between both approaches.

But it will take investigation, when time and resources permit, so in the mean time I can only suggest creating a GitHub issue with this information, and emulating the working example I linked more closely. (i.e. use and app with a doc handler configured and don’t push sessions by hand)
Also, do you have any suggestions on how can I work on this? I can’t have a function like modify_doc. Also, can you suggest me other handlers like SessionHandler or FunctionHandler? Any pointers to how can I create a personalized one?

Thanks for your help. I can move the discussion to Github but this is not a bug reporting. Are you sure I should move this to Github?

Regards,

Kartik

Hi,

First of all, I can't have more than one Document instance per Server. I want the server to run and then start the streaming data. I can't have more than one Document instance because if I change a parameter of simulation from one client, I can't run the separate program for other Document instance on another client. Now, to keep a common session and hence, common document, I must have known session (identified by sessionID) and corresponding Document. As far as I understand, a normal typical Server process will create separate sessions, hence, separate Documents.

First I should say that it's possible that Bokeh is not the appropriate tool for your use case. Google-doc style "sharing" is a use-case we do not specialize for. Which is not to say it's impossible in some cases, but we have made explicit trade offs that favor different usage patterns than that.

However, instead of trying to get Bokeh to do something in a way it's not really good at, I'd suggest considering a different approach. Take a look at the spectrogram example:

  https://github.com/bokeh/bokeh/tree/master/examples/app/spectrogram

In that example there is one source of data, a single thread recording (or generating) acoustic data. The every session displays this same data. There's not currently anything that would change the parameters of audio data stream based on client-interaction, but it's not hard to imagine a button or slider callback, that changes some module parameter of the audio.py file, such that the thread *reacts* to the new value, and starts generating new or different data (that all the clients will react to and see).

Or put another way: I think your best bet for using Bokeh here is to make the apps standard ones (new session/doc per client), that are simply lightweight reactive views of a single central source of data. The single source could be a shared read-only data structure as in the spectrogram, or a common database, or zmq connections to a central sim, or any number of things. Then have callbacks for widgets inform whatever is generating the data of any necessary changes. Then any connected apps viewing the source will see new data when it updates.

I m afraid I don't understand what do you mean by "splitting the difference between both approaches".

I mean that you are trying to use elements of usage from two different paradigms: i) the "bokeh.client" paradigm that has a *separate* python process, both from the bokeh server and from any embedding web app, that uses push_session, etc. and ii) the standard and recommended bokeh app/embedded bokeh server usage. I don't know that this can be supported or expected to work.

Also, do you have any suggestions on how can I work on this? I can't have a function like modify_doc. Also, can you suggest me other handlers like SessionHandler or FunctionHandler? Any pointers to how can I create a personalized one?

There is no way. The method modify_doc is the *defining* interface for a Handler. All Handler subclasses *must* define modify_doc so that they can be used to handle new sessions (by creating/modifying docs for the session). That is their explicit purpose.

Thanks for your help. I can move the discussion to Github but this is not a bug reporting. Are you sure I should move this to Github?

At this point, I agree that GitHub is not suitable.

Thanks,

Bryan

···

On Jul 13, 2017, at 04:07, Kartik Patel <[email protected]> wrote:

Dear Bryan,

Thank you very much for your response. I now understand what documentation tried to explain about Client API and Server API.

As of now, I will continue to use “Google Doc” like sharing (because that’s what driven me to select Bokeh in the first place). But I can keep it, if and only if you are not planning to end it in the first version of Bokeh (Are you planning to end it?). I will arrange to call bokeh serve command externally or using Python. I updated the file accordingly and callbacks are working fine.

Regards,

Kartik

···

On Thursday, July 13, 2017 at 7:20:33 PM UTC+5:30, Bryan Van de ven wrote:

Hi,

On Jul 13, 2017, at 04:07, Kartik Patel [email protected] wrote:

First of all, I can’t have more than one Document instance per Server. I want the server to run and then start the streaming data. I can’t have more than one Document instance because if I change a parameter of simulation from one client, I can’t run the separate program for other Document instance on another client. Now, to keep a common session and hence, common document, I must have known session (identified by sessionID) and corresponding Document. As far as I understand, a normal typical Server process will create separate sessions, hence, separate Documents.

First I should say that it’s possible that Bokeh is not the appropriate tool for your use case. Google-doc style “sharing” is a use-case we do not specialize for. Which is not to say it’s impossible in some cases, but we have made explicit trade offs that favor different usage patterns than that.

However, instead of trying to get Bokeh to do something in a way it’s not really good at, I’d suggest considering a different approach. Take a look at the spectrogram example:

    [https://github.com/bokeh/bokeh/tree/master/examples/app/spectrogram](https://github.com/bokeh/bokeh/tree/master/examples/app/spectrogram)

In that example there is one source of data, a single thread recording (or generating) acoustic data. The every session displays this same data. There’s not currently anything that would change the parameters of audio data stream based on client-interaction, but it’s not hard to imagine a button or slider callback, that changes some module parameter of the audio.py file, such that the thread reacts to the new value, and starts generating new or different data (that all the clients will react to and see).

Or put another way: I think your best bet for using Bokeh here is to make the apps standard ones (new session/doc per client), that are simply lightweight reactive views of a single central source of data. The single source could be a shared read-only data structure as in the spectrogram, or a common database, or zmq connections to a central sim, or any number of things. Then have callbacks for widgets inform whatever is generating the data of any necessary changes. Then any connected apps viewing the source will see new data when it updates.

I m afraid I don’t understand what do you mean by “splitting the difference between both approaches”.

I mean that you are trying to use elements of usage from two different paradigms: i) the “bokeh.client” paradigm that has a separate python process, both from the bokeh server and from any embedding web app, that uses push_session, etc. and ii) the standard and recommended bokeh app/embedded bokeh server usage. I don’t know that this can be supported or expected to work.

Also, do you have any suggestions on how can I work on this? I can’t have a function like modify_doc. Also, can you suggest me other handlers like SessionHandler or FunctionHandler? Any pointers to how can I create a personalized one?

There is no way. The method modify_doc is the defining interface for a Handler. All Handler subclasses must define modify_doc so that they can be used to handle new sessions (by creating/modifying docs for the session). That is their explicit purpose.

Thanks for your help. I can move the discussion to Github but this is not a bug reporting. Are you sure I should move this to Github?

At this point, I agree that GitHub is not suitable.

Thanks,

Bryan

As of now, I will continue to use "Google Doc" like sharing (because that's what driven me to select Bokeh in the first place). But I can keep it, if and only if you are not planning to end it in the first version of Bokeh (Are you planning to end it?). I will arrange to call `bokeh serve` command externally or using Python. I updated the file accordingly and callbacks are working fine.

There are no plans to remove bokeh.client or push_session, etc.

Thanks,

Bryan

···

On Jul 13, 2017, at 13:58, Kartik Patel <[email protected]> wrote:

Regards,
Kartik

On Thursday, July 13, 2017 at 7:20:33 PM UTC+5:30, Bryan Van de ven wrote:
Hi,

> On Jul 13, 2017, at 04:07, Kartik Patel <[email protected]> wrote:
>
> First of all, I can't have more than one Document instance per Server. I want the server to run and then start the streaming data. I can't have more than one Document instance because if I change a parameter of simulation from one client, I can't run the separate program for other Document instance on another client. Now, to keep a common session and hence, common document, I must have known session (identified by sessionID) and corresponding Document. As far as I understand, a normal typical Server process will create separate sessions, hence, separate Documents.

First I should say that it's possible that Bokeh is not the appropriate tool for your use case. Google-doc style "sharing" is a use-case we do not specialize for. Which is not to say it's impossible in some cases, but we have made explicit trade offs that favor different usage patterns than that.

However, instead of trying to get Bokeh to do something in a way it's not really good at, I'd suggest considering a different approach. Take a look at the spectrogram example:

        https://github.com/bokeh/bokeh/tree/master/examples/app/spectrogram

In that example there is one source of data, a single thread recording (or generating) acoustic data. The every session displays this same data. There's not currently anything that would change the parameters of audio data stream based on client-interaction, but it's not hard to imagine a button or slider callback, that changes some module parameter of the audio.py file, such that the thread *reacts* to the new value, and starts generating new or different data (that all the clients will react to and see).

Or put another way: I think your best bet for using Bokeh here is to make the apps standard ones (new session/doc per client), that are simply lightweight reactive views of a single central source of data. The single source could be a shared read-only data structure as in the spectrogram, or a common database, or zmq connections to a central sim, or any number of things. Then have callbacks for widgets inform whatever is generating the data of any necessary changes. Then any connected apps viewing the source will see new data when it updates.

> I m afraid I don't understand what do you mean by "splitting the difference between both approaches".

I mean that you are trying to use elements of usage from two different paradigms: i) the "bokeh.client" paradigm that has a *separate* python process, both from the bokeh server and from any embedding web app, that uses push_session, etc. and ii) the standard and recommended bokeh app/embedded bokeh server usage. I don't know that this can be supported or expected to work.

> Also, do you have any suggestions on how can I work on this? I can't have a function like modify_doc. Also, can you suggest me other handlers like SessionHandler or FunctionHandler? Any pointers to how can I create a personalized one?

There is no way. The method modify_doc is the *defining* interface for a Handler. All Handler subclasses *must* define modify_doc so that they can be used to handle new sessions (by creating/modifying docs for the session). That is their explicit purpose.

> Thanks for your help. I can move the discussion to Github but this is not a bug reporting. Are you sure I should move this to Github?

At this point, I agree that GitHub is not suitable.

Thanks,

Bryan

--
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[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/b2336c4c-af28-4acb-8669-459caf86b25e%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.