Voila button not working

Hi all,

I am new here and I am trying to develop a Voila app based on a jupyter notebook. Unfortunately, the buttons are not working as expected so I hope you can give me some help.

I currently have the code below. What I doing wrong here?

input_file = widgets.Text(
    value='Input file path',
    placeholder='Input file path',
    description='Input file:',
    disabled=False,
    layout = widgets.Layout(width='1000px')
)
export_folder = widgets.Text(
    value='Output folder directory',
    placeholder='Output folder directory',
    description='Export folder:',
    disabled=False,
    layout = widgets.Layout(width='1000px')
)
button = widgets.Button(
    description='Run analysis',
    disabled=False,
    button_style='',
    tooltip='Click me',
    icon='play'
)
display(input_file)
display(export_folder)
display(button)

class Analysis:
    def __init__(self, input_file_path, export_path):
        self.df_input = pd.read_excel(f'{input_file_path})
        self.export_path = export_path

    def run(self):
        self.output = run_analysis(self.df_input)
        self.output.to_csv(f"{self.export_path}/results.csv")
        print('Analysis completed. Results saved in output folder')
        
def callback_button(input_file_path, export_path):
    try:
        Analysis(input_file_path, export_path).run()
    except Exception as e:
        print(f'Error running analysis: {e}')

button.observe(callback_button(input_file.value, export_folder.value), names='value')

This provided code block isn’t complete and so it is hard to judge what you mean by the vague statement that “the buttons are not working as expected”. What example code is it based on? Maybe start with that to make a minimal reproducible example?

Thank you for your quick answer. To make it easier, as an initial step/testing, all I want to do is:

  1. Have a text box to input an excel file directory path ;
  2. Have a text box to write a directory where a panda dataframe will be saved in .csv format;
  3. Run button: reads an excel file from 1. to a pandas dataframe and outputs it to the output directory from 2. Print in the app: 'File saved in {output directory}.

I tried to base my code on this app: https://github.com/voila-gallery/voila-spotify/blob/625f0d3eb7472db4f355fdd8ab522c5bebf291c7/Spotify_viewer.ipynb

import ipywidgets as widgets
from IPython.display import display
import pandas as pd

input_file = widgets.Text(
    value='Input file path',
    placeholder='Input file path',
    description='Input file:',
    disabled=False,
    layout = widgets.Layout(width='1000px')
)
export_folder = widgets.Text(
    value='Output folder directory',
    placeholder='Output folder directory',
    description='Export folder:',
    disabled=False,
    layout = widgets.Layout(width='1000px')
)
button = widgets.Button(
    description='Run',
    disabled=False,
    button_style='',
    tooltip='Click me',
    icon='play'
)

def button_clicked(event):
    df = pd.read_excel(input_file.value)
    df.to_csv(f'{export_folder.value}/copied_file.csv')
    print(f'File saved in {export_folder.value}')
    
button.on_click(button_clicked)

display(input_file)
display(export_folder)
display(button)

Your code seems to work in a JupyterLab cell and Voila in my hands in that in Voila I get a copy of the data my csv file put in the directory I specify, saved as copied_file.csv.

In my case, I had to change your read excel line to the following because I was using a CSV file and not an excel file.

df = pd.read_csv(input_file.value)

The one thing that doesn’t quite work is that your File saved in message goes to the log when I first execute it in JupyterLab. It seems to go off to nowhere in Voila. This handling is as it should be because you aren’t assigning it to the widgets output handling necessary for modern use of ipywidgets upon which Voila is based, see this thread, especially the last post.

Since you write in three you want, “Print in the app: 'File saved in {output directory}”, I’ll see what I’d suggest in a separate reply so it doesn’t get buried. However, I wanted to point out that no where in your post did you say what you saw not working. And so I cannot be sure your experience is the same as mine here. And as people trying to help you, we shouldn’t be left to dissect these things and guess what you mean. In other words, the title of ‘Voila button not working’ and ’ Unfortunately, the buttons are not working as expected’ are insufficient. You may be experiencing something completely different and so what I’ve seen isn’t reproducing what you are experiencing. Please read Getting good answers to your questions and use it as a guide going forward.


Minor aside now, since your code does seem to work it is rather moot but I’ll point out…:

What aspect is based on that as a starting point? I cannot see any semblance of similarity in the code. If that one you linked to works then actually step through slowly changing it to match your needs.

The following code works in my hands in both JupyterLab and Voila:

import ipywidgets as widgets
from IPython.display import display
import pandas as pd

input_file = widgets.Text(
    value='Input file path',
    placeholder='Input file path',
    description='Input file:',
    disabled=False,
    layout = widgets.Layout(width='1000px')
)
export_folder = widgets.Text(
    value='Output folder directory',
    placeholder='Output folder directory',
    description='Export folder:',
    disabled=False,
    layout = widgets.Layout(width='1000px')
)
button = widgets.Button(
    description='Run',
    disabled=False,
    button_style='',
    tooltip='Click me',
    icon='play'
)

out = widgets.Output()

def button_clicked(event):
    df = pd.read_csv(input_file.value)
    df.to_csv(f'{export_folder.value}/copied_file.csv')
    with out:
        print(f'File saved in {export_folder.value}')
    
button.on_click(button_clicked)

display(input_file)
display(export_folder)
display(button)
display(out)

I’m not fond of the way of handling the status with the print statement, but it works.
If you want I can point you to a place where it runs in a session served via MyBinder.org if you aren’t experiencing the same thing. Then you can compare behavior and versions if you want.