Skip to content
This repository has been archived by the owner on Oct 26, 2019. It is now read-only.

Button which rerunns all cells in jupyter notebook does not work on dashboard server #300

Closed
romario076 opened this issue Oct 27, 2016 · 5 comments

Comments

@romario076
Copy link

romario076 commented Oct 27, 2016

Hi !
We have multi cell notebook wich requires one input - Date, and each time the input is changed i need to rerun all cells with code to generate new outputs. I use grid dashboard layout.
The button works in jupyter notebook dashboard however it does not work when i deploy my notebook to dashboard server.

Here is the code .

image

I get following error in browser after clicking on button on dashboard server.
capture

If you know any solution for reruning all notebook cells on deployed app with one input parameter.
Please help to find any solution.

@parente
Copy link
Member

parente commented Nov 9, 2016

Hi @romario076 . The custom require calls you're making in your notebook are not supported in the dashboard server which does not have the notebook JS modules. I'm not sure it ever will since it's building off of the new Jupyter Lab components rather than embedding all of the classic notebook JS files.

We need to do a better job of scoping and documenting what can work in the dashboard server, what cannot but could with improvements, and what will probably never work.

@bowenli37
Copy link

bowenli37 commented Nov 28, 2016

We used ipywidgets.interact to achieve the same behavior, that is, to allow user to update dashboards by providing inputs on dashboards server.

class Model:
    @classmethod
    def load_data(self):
        # Load data from somewhere
        return data

class Controller:
    def __init__(self):
        self.data = Model.load_data()
        self.widgets = OrderedDict({
            'widget': widget(self)
        })
        # it is a hidden element to trigger show()
        self.trigger = Checkbox(value = False,
                                description='',
                                layout=Layout(visibility='hidden'))
        display(self.widgets['widget'].form)
        interact(self.show, x = self.trigger)
        
        
    def button_action(self):
        # change trigger
        self.trigger.value = not self.trigger.value
        

    def plot1(self):
        # do plot1
        return

    def plot2(self):
        # do plot2
        return
    
    def show(self, x):
        self.plot1()
        self.plot2()
        
class widget:
    # pass controller to constructor
    def __init__(self, controller):
        # build a form with ipywidgets elements
        # suppose you have a button that triggers refresh
        button = Button(description = 'Click to update', button_style = 'info')
        

        # Form event
        def button_handler(sender):
            controller.button_action()
            
        button.on_click(button_handler)

To display the dashboards, just do

controller = Controller()

Then you have to restructure your cells into functions like Controller.plot1(). This way you don't need to rerun all the cells, just one function Controller.show(). It breaks our usual coding pattern as in an interactive notebook, but this is as close as we can get if we want to achieve the desired behavior.

@parente
Copy link
Member

parente commented Jan 20, 2017

@bowenli37 thanks for sharing that recipe.

There's also been work (jupyter/jupyter_client#209) to support an update_display message as part of the Jupyter protocol which should make updating cell outputs easier in the future.

@parente parente closed this as completed Jan 20, 2017
@dwkenefick
Copy link

Hi all,
Sorry to comment on something long dead, but I have a similar problem and nothing seems to be working.

I have a dashboard with a single set of inputs, and I would like those inputs to update charts in several different cells. I can use a Javascript call in a notebook, but this does not work once the dashboard is deployed.

Things I've tried:

  • ipywidgets.Output: In the cell containing each chart, I create a separate output widget to hold each chart. Once the inputs are updated, a handler function calls updates each chart like this:
# Chart Cell: set up chart
chart_container = ipywidgets.Output()
display(chart_container)

def update_chart(plotting_object):
    chart_container.clear_output()
    with chart_container:
        plotting_object.plot()

# Later Cell: handler function
def button_handler(sender):
    update_chart(plotting_object)  

This works fine in the notebook and dashboard preview, but the charts do not update once the dashboard is deployed.

  • IPython.display.update_display: In the cell containing each chart, I use display to show each chart and provide a display_id. Once the inputs are updated, a handler function calls update_display on each display_id with the new chart. Once the dashboard is deployed, the cells containing the charts do not update.
  • @bowenli37's recipe: This too does not seem to work: the trigger does not seem to work once the dashboard is deployed. Even in the notebook, the charts appear in the cell where I called controller = Controller() rather than controller.plot1()

I want to arrange the charts nicely in a grid format, so running everything from a single cell probably wont work. I could also have a separate submit button for each chart (which works) but would be obnoxious.

Ultimately, I need to trigger a display update for one cell from another cell while the dashboard is running. Can anyone see flaws in my general approach, or suggest something that will give me equivalent results?

Let me know if I can clarify, or if I should open another issue.

@funnydevnull
Copy link

@dwkenefick have you had any luck with this? I'm in exactly the same position and I've tried similar solutions to no avail. I've found some ipywidget discussion (issue 1410) about the fact that the Output widget is not supported in the context of embedded HTML (which I presume is what the dashboard is). There they claim that its been fixed but this is quite recent and I'm not sure the fix has made it into the current distribution. Can anyone who understands this better comment on whether this fix will likely resolve @dwkenefick's (and my) problem?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants