File size: 1,836 Bytes
2b4d75c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# Background Tasks / Progress
# Execute background functions while incrementing a #progress bar.
# #background_tasks
# ---
import time
import asyncio
import concurrent.futures
from h2o_wave import main, app, Q, ui
# A long-running that performs a blocking operation, in this case time.sleep()
def blocking_function(secs) -> str:
time.sleep(secs) # Blocks!
return 'Download completed!'
# An async function that displays a progress bar
async def display_progress_bar(q: Q, form, seconds: int):
for i in range(seconds):
progress_value = (i + 1.0) / seconds
form.items = [
ui.progress(
label='Downloading the interwebs...',
caption=f'{int(progress_value * 100)}%',
value=progress_value,
)
]
await q.page.save()
await q.sleep(1)
@app('/demo')
async def serve(q: Q):
if q.args.start: # The button named 'start' was clicked
seconds = 5
# Grab a reference to the form
form = q.page['form']
# Start incrementing the progress bar in the background
future = asyncio.ensure_future(display_progress_bar(q, form, seconds))
# Execute our long-running function in the background
with concurrent.futures.ThreadPoolExecutor() as pool:
message = await q.exec(pool, blocking_function, seconds)
# Stop the progress bar (optional unless we used a infinite while loop in display_progress_bar()).
future.cancel()
# At this point, we're done with the long-running function; so display a completion message
form.items = [ui.message_bar('info', message)]
await q.page.save()
else:
q.page['form'] = ui.form_card(box='1 1 2 2', items=[ui.button(name='start', label='Start')])
await q.page.save()
|