Run async functions in Jupyter Notebook

I’m trying to get the following behavior when the user clicks the button I’ve defined in the code block below:

  1. The print_async routine inside of it is invoked, which waits for 2 seconds and then prints "“this is async print from buttonCLicked”
  2. Then I want the print after which is “button clicked!” to appear.

However, I’m getting an interpreter error instead:

File “cell_name”, line 6 SyntaxError: ‘await’ outside async function

from IPython.display import display
from ipywidgets import widgets
import asyncio
#DO NOT CHANGE THIS CELL
#Define an async function
async def print_async(message):
    await asyncio.sleep(2)
    print(message)
# Show that we can print from the top-level jupyter terminal
await print_async("This is a top-level async print")
#Define a callback function for the button
def onButtonClicked(_):
    await print_async("this is async print from buttonCLicked")
    print("button clicked!")

button = widgets.Button(
    description='Click me',
    disabled=False,
    button_style='', # 'success', 'info', 'warning', 'danger' or ''
    tooltip='Click me',
    icon=''
)

button.on_click(onButtonClicked)
display(button)

I’m having trouble getting the expected behavior when the user clicks the button defined in the code block above. The goal is for the print_async routine to be invoked, which waits for 2 seconds and then prints "“this is async print from buttonCLicked”, then for the print after which is “button clicked!” to appear. Instead, I’m getting the following interpreter error:

File “cell_name”, line 6 SyntaxError: ‘await’ outside async function

You need to define the onButtonClicked function as an async function by adding async before the function definition. Here’s the corrected code:

from IPython.display import display
from ipywidgets import widgets
import asyncio

# Define an async function
async def print_async(message):
    await asyncio.sleep(2)
    print(message)

# Show that we can print from the top-level jupyter terminal
await print_async("This is a top-level async print")

# Define a callback function for the button
async def onButtonClicked(_):
    await print_async("this is async print from buttonCLicked")
    print("button clicked!")

button = widgets.Button(
    description='Click me',
    disabled=False,
    button_style='', # 'success', 'info', 'warning', 'danger' or ''
    tooltip='Click me',
    icon=''
)

button.on_click(onButtonClicked)
display(button)

Note that the onButtonClicked function is now defined as async def onButtonClicked(_).