Button on_click with async function that takes additional arguments

I need to asyncify a function that I have that takes two positional arguments when applying it in the button.on_click() method. How can I enhance the code found in the documentation?


import panel as pn
pn.extension()

button1 = pn.widgets.Button(name='Click me!')
button2 = pn.widgets.Button(name='Click me too!')

text = pn.widgets.StaticText()

def run(arg1, arg2):
    text.value = f'Running {event.new}'
    text.value = f'Finished {event.new}'

button1.on_click(lambda event: run('hi', 'hello')
button2.on_click(lambda event: run('bye', 'goodbye')

The way I want to do it would look oddly like this, but I’m sure there’s an error somewhere. I need to asyncify the run method. How do I do it?

maybe

from itertools import partial
partial(run, arg2="hello")

does it make it asynchronous?

No, you have to make run async

You can use partial as shown below.

import panel as pn
from functools import partial
from asyncio import sleep

pn.extension()

button1 = pn.widgets.Button(name='Click me!')
button2 = pn.widgets.Button(name='Click me too!')

text = pn.widgets.StaticText()

async def run(event, arg1, arg2):
    text.value = f'Running {event.new} {arg1} {arg2}'
    await sleep(1)
    text.value = f'Finished {event.new} {arg1} {arg2}'

button1.on_click(partial(run,arg1='hi', arg2='hello'))
button2.on_click(partial(run,arg1='bye', arg2='goodbye'))

pn.Column(
    text, button1, button2
).servable()

Alternative pn.bind

You can also use pn.bind instead of partial

import panel as pn
from functools import partial
from asyncio import sleep

pn.extension()

button1 = pn.widgets.Button(name='Click me!')
button2 = pn.widgets.Button(name='Click me too!')

text = pn.widgets.StaticText()

async def run(event, arg1, arg2):
    text.value = f'Running {event.new} {arg1} {arg2}'
    await sleep(1)
    text.value = f'Finished {event.new} {arg1} {arg2}'

button1.on_click(pn.bind(run,arg1='hi', arg2='hello'))
button2.on_click(pn.bind(run,arg1='bye', arg2='goodbye'))

pn.Column(
    text, button1, button2
).servable()
1 Like