散景服务器和on.click(on.change)什么都不做

时间:2016-09-16 14:02:22

标签: python bokeh

我试图让Bokeh服务器打印出来,但是我得到的是一个在http://localhost:5006/?bokeh-session-id=default上运行带有单选按钮的实例。当我点击按钮时没有任何反应。有什么我想念的吗?

from bokeh.models.widgets import RadioButtonGroup
from bokeh.plotting import figure, show, output_server


def my_radio_handler():
    print 'Radio button option selected.'


radio_button_group = RadioButtonGroup(
        labels=["Option 1", "Option 2", "Option 3"], active=0)

radio_button_group.on_click(my_radio_handler)

output_server()

show(radio_button_group)

2 个答案:

答案 0 :(得分:6)

上面的答案显示了如何使用bokeh.clientpush_session以及session.loop_until_closed正确完成此操作。

我想为上下文添加一些注释。 (我是Bokeh项目的核心开发人员)

Bokeh应用程序可以运行两种常规方法:

直接在服务器

这些脚本的运行方式如下:

bokeh serve --show my_app.py

在这种情况下,代码,对象,所有回调等都在散景服务器本身中运行情况如下:

                          browser <---> Bokeh Server

这是我一直建议的方法。它需要的代码量最少,部署最简单,可以扩展,使用较少的网络流量,并且更加强大。

在单独的Python进程中

还可以使用bokeh.client在单独的流程中创建应用并运行回调。情况如下:

               browser <---> Bokeh Server <---> another python process

然后,Bokeh服务器真正成为中间人,在浏览器和python进程之间传递消息。这有缺点:

  • 使网络流量加倍(对于新的python进程,根据定义不可避免)
  • 需要更多代码来编写(#34;服务器应用程序&#34;)所需的所有session内容。
  • 要求python进程无限期地阻止为回调提供服务(必须调用session.loop_until_closed

过去,有一些特定的用例需要使用bokeh.client,例如:能够自定义每次使用的应用会话。但现在,HTML请求参数可用于&#34;服务器应用程序&#34;这可以在没有bokeh.client的情况下完成。我想说现在有更少的理由可以达到bokeh.client方法。出于这个原因 我总是建议使用bokeh serve my_app.py方法作为使用Bokeh服务器的第一个最佳方式

但是,回到手头的问题:那么,如果您忘记拨打session.loop_until_closed,那么 Separate Python Process 场景会发生什么?好吧,python进程(具有你的回调的进程!)完成,进程终止。然后没有什么可以实际运行回调。

嗯,这基本上与output_server的情况完全相同。这是&#34;上半年&#34;会话设置,将对象加载到服务器,然后调用output_server的python脚本完成,没有任何东西可以执行任何回调。由于历史事故,output_server基本上仍然存在,但我认为它根本不是很有用。最好的情况是,它可以将没有回调的应用程序加载到Bokeh服务器中,但是为什么除了将Web应用程序连接到真正的python回调之外,你还需要一个Bokeh服务器?

目前(截至发布0.12.2)有一个未解决的问题,因为这个原因讨论了弃用output_server

https://github.com/bokeh/bokeh/issues/5154

TLDR; 此时我不建议出于任何原因使用output_server

答案 1 :(得分:2)

您需要同步服务器和当前会话以获取信息。

from bokeh.client import push_session
from bokeh.models.widgets import RadioButtonGroup
from bokeh.plotting import curdoc, figure, show, output_server


def my_radio_handler(new):
    print 'Radio button ' + str(new) + ' option selected.'


radio_button_group = RadioButtonGroup(
    labels=['Option 1', 'Option 2', 'Option 3'], active=0)
radio_button_group.on_click(my_radio_handler)

# Open a session to keep our local document in sync with server
session = push_session(curdoc())

# Open the document in a browser
session.show(radio_button_group)

# Run forever (this is crucial to retrive callback's data)
session.loop_until_closed()

您可以使用on_change()获得对点击处理程序的更多控制权:

def my_radio_handler_complete(attr, old, new):
    print(attr, old, new)
    print('Radio button ' + str(new) + ' option selected.')

radio_button_group.on_change('active', my_radio_handler_complete)

仅供参考,在源代码中,on_click只是on_change()的代理,定义为:

def on_click(self, handler):
   self.on_change('active', lambda attr, old, new: handler(new))