mljar / mercury

Convert Jupyter Notebooks to Web Apps
https://RunMercury.com
GNU Affero General Public License v3.0
4.05k stars 256 forks source link

Numeric widgets trigger unnecessary reloading of upstream cells #472

Open clami66 opened 1 month ago

clami66 commented 1 month ago

I am building an application on mercury v.2.4.3. A simplified version of the interface is as follows:

Cell 1:

model_type = mr.Select(label="Select model type", choices=["v1", "v2"])

n_predictions = mr.Numeric(value=1, min=1, max=10, label="Number of predictions", step=1)

n_recycles = mr.Numeric(value=1, min=1, max=5, label="Number of recycles", step=1)

use_dropout = mr.Checkbox(value=True, label="Enable dropout")

run_pred = mr.Button(label="Run predictor")
if run_pred.clicked:
    preds = predict(model_type.value, n_predictions.value, n_recycles.value, use_dropout.value)

Cell 2:

n = mr.Select(label="Select prediction to plot", choices=list(range(len(preds))))
plot(preds[n])

My understanding is that, after getting the results from Cell 1, changing the selection on Cell 2 should only update the plots.

This is fine if I don't change any of the settings in Cell 1 before launching the prediction.

However, if I have changed n_predictions or n_recycles from, e.g. 1 to 2, before running the predictor, then both cells are re-executed, even when I just select a different plot in Cell 2 (i.e. the menu refreshes back to a stage where I should click on the run_pred button). This doesn't happen for widgets of other kinds (checkboxes or dropdown menus).

I have run the server with mercury run --verbose and in the logs I can see:

NB 2024-10-15 09:13:08,912 Update reponse [{'data': {'text/plain': ['False']}, 'metadata': {}, 'output_type': 'execute_result', 'execution_count': 30}], **updated=False**
NB 2024-10-15 09:13:08,913 Update widget code_uid=Select.16.50.104.8 value=0 widget type Select
NB 2024-10-15 09:13:08,913 Execute code WidgetsManager.update("Select.16.50.104.8", field="value", new_value="""0""")
NB 2024-10-15 09:13:08,915 Update reponse [{'data': {'text/plain': ['True']}, 'metadata': {}, 'output_type': 'execute_result', 'execution_count': 31}], updated=True
NB 2024-10-15 09:13:08,915 Widget updated, update nb from 16
NB 2024-10-15 09:13:08,916 Update widget code_uid=Checkbox.16.50.70.12 value=True widget type Checkbox
NB 2024-10-15 09:13:08,916 Execute code WidgetsManager.update("Checkbox.16.50.70.12", field="value", new_value=True)
NB 2024-10-15 09:13:08,918 Update reponse [{'data': {'text/plain': ['False']}, 'metadata': {}, 'output_type': 'execute_result', 'execution_count': 32}], updated=False

What I think is happening is that changing from the default values in mr.Numeric widgets will permanently cause them tho show as updated (updated=True as per the logs), even when they are not.

So far, I have fixed this by replacing al mr.Numeric widgets to mr.Select, which fixes the issue. But it would be great to know if this is an expected behavior, or if I'm using the numeric widgets incorrectly.

Thanks!

pplonski commented 1 month ago

Hi @clami66,

Thank you for reporting the issue. I would try to split widgets code into separate cells. At least I would put prediction code in the separate cell:

if run_pred.clicked:
    preds = predict(model_type.value, n_predictions.value, n_recycles.value, use_dropout.value)

I'm glad that switching Numeric to Select is solving the issue for now. I would need more time to dig into this issue.

BTW, are you happy with your web app created in Mercury? :)

clami66 commented 1 month ago

Hi @pplonski

Thanks for the quick response! I probably over-simplified the code, the "prediction" code is already in its own cell. So in the example above it would be on its own in cell 2, then cell 3 with the plots. So that unfortunately doesn't fix it.

The current draft of the notebook is already public, so you can also take a look at it yourself here if you'd like.

BTW, are you happy with your web app created in Mercury? :)

I'm very happy with the app, thanks! I think it's a good alternative to a colab notebook, especially if you want to host it on your own server and don't want people to be able to edit the code.