How do I add a callback with arguments to a button?

Hi, I’m trying to do something conceptually very simple, but somehow still failing to figure it out. I just want to be able to call a function with some arguments when I click a button.

def add_data(event, some_data, list_of_data):
	print(event)
	list_of_data.append(some_data)

def main():
	validationButton = pn.widgets.Button(name='Validate', button_type='primary')
	validationButton.on_click(add_data)

Obviously, this doesn’t work, as I’m not providing some_data and list_of_data to add_data(), but I can’t find a way to do so that actually works.

If I remove these two arguments from add_data() and only leave event as an argument, this executes as expected. I tried messing around with binding or decorators, but with no success. The only thing that does work is to make some_data and list_of_data global variables, but there must be a way to do this in a cleaner fashion.

Any advice?

You should be able to achieve the desired result using functools.partial

from functools import partial

def add_data(event, some_data, list_of_data):
	print(event)
	list_of_data.append(some_data)

def main():
	validationButton = pn.widgets.Button(name='Validate', button_type='primary')
        some_data = "something"
        list_of_data = []
	validationButton.on_click(partial(add_data, some_data, list_of_data))
2 Likes

Indeed! It seems the problem wasn’t my lack of Panel expertise as much as my lack of Python expertise, in this case. Thank you very much!

Just one minor thing: it appears that doing this ends up putting the event argument last when calling add_data(), so its prototype must be modified accordingly:

from functools import partial

def add_data(some_data, list_of_data, event):
	print(event)
	list_of_data.append(some_data)

def main():
	validationButton = pn.widgets.Button(name='Validate', button_type='primary')
        some_data = "something"
        list_of_data = []
	validationButton.on_click(partial(add_data, some_data, list_of_data))
1 Like