<jupyter_start><jupyter_text>This NB is to demo the Bokeh Widget 2-way Synchronization With a Bokeh ServerWidget Python Obj  Widget UI First Demo a Not-working example on registering python callback to listen to UI changes<jupyter_code>from bokeh.io import output_file, show, output_notebook, push_notebook
import param
import parambokeh
import numpy as np

output_notebook()

class BokehSliderParam(param.Parameterized):    
    
    # define param parameters    
    slider_value = param.Number(default=1.0, bounds=(0, 100))<jupyter_output><empty_output><jupyter_text>Now embed a bokeh server and start a bokeh app<jupyter_code>from bokeh.layouts import widgetbox
import time


# This is a bokeh app! Should run with a bokeh server!!
# This bokeh can run outside of jupyter as well!
# bokeh widget on_change event (bokeh widget python callback) only works with a bokeh server
def modify_doc(doc):    
    
    myslider_param = BokehSliderParam()
    #parambokeh.Widgets(myslider_param, doc=doc, mode="server", callback=UI_changed)   
    widget_obj=parambokeh.Widgets.instance()
    
    # Python callback to response to UI changes
    def UI_changed(self, **kwargs):        
        print ("UI change triggered Param Obj change? {0}".format(self.slider_value))
        print ("UI change triggered Widget Python Obj change? {0}".format(widget_obj._widgets["slider_value"].value)) 
    
    
    widget_obj(myslider_param, doc=doc, mode="server", callback=UI_changed)   
    
    # A func to demo changing python Obj
    def update_python_obj():                   
        myslider_param.slider_value = np.random.randint(0,100)
        print("Updating Param Obj to {}".format(myslider_param.slider_value))
        print("UI changed?")
        print("Widget Python Obj changed? {}".format(widget_obj._widgets["slider_value"].value))
        
#         widget_obj._widgets["slider_value"].value = np.random.randint(0,100)
#         print("Updating Widget Python Obj to {}".format(widget_obj._widgets["slider_value"].value))
#         print("UI changed?")
#         print("Param Obj changed? {}, {}".format(myslider_param.slider_value, widget_obj.parameterized.slider_value))
  
    
    # Call periodic func to change widget python obj
    doc.add_periodic_callback(update_python_obj, 3000)



# start bokeh server and app
app = show(modify_doc)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09393428812131424, 'fraction_numerical': 0.008845829823083403, 'mean_word_length': 3.9376299376299375, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '653771', 'license': 'MIT', 'n_tokens_mistral': 753, 'n_tokens_neox': 735, 'n_words': 199, 'path': 'reviews/Jupyter_Widgets/param/ParamBokeh_widget_UI_to_Param_one_way_with_bokeh_server.ipynb', 'repo_name': 'Aquaveo/jupyter_to_tethys', 'size': '2374'}