Skip to content

Instantly share code, notes, and snippets.

@mturoci
Created September 20, 2022 16:23
Show Gist options
  • Save mturoci/4a38e59b37661b4d7d83d4a721d60c93 to your computer and use it in GitHub Desktop.
Save mturoci/4a38e59b37661b4d7d83d4a721d60c93 to your computer and use it in GitHub Desktop.
import concurrent.futures
from h2o_wave import main, app, Q, ui
import boto3
import asyncio
def download(q: Q, loop: asyncio.AbstractEventLoop):
bucket = 'h2o-wave'
file_key = 'releases/h2o_wave-0.22.0-py3-none-win_amd64.whl'
# Get the total size of the file.
total = boto3.client('s3').head_object(Bucket=bucket, Key=file_key)['ContentLength']
already_downloaded = 0
# Nested update function that is called periodically from within boto.
def update(val):
nonlocal already_downloaded
already_downloaded += val
# Update the Wave UI.
asyncio.ensure_future(update_ui(q, already_downloaded / total), loop=loop)
# Since boto3 is synchronous, this download is blocking.
boto3.resource('s3').Bucket(bucket).download_file(
file_key, 'hello.whl', Callback=update
)
asyncio.ensure_future(show_notification(q), loop=loop)
async def show_notification(q: Q):
q.page['meta'].dialog = None
q.page['meta'].notification_bar = ui.notification_bar(
name='success_notification',
text='Job done!',
type='success',
events=['dismissed']
)
await q.page.save()
async def update_ui(q: Q, value: int):
q.page['meta'].dialog.items[0].progress.value = value
await q.page.save()
@app('/')
async def serve(q: Q):
# Unimportant, draw initial UI.
if not q.client.initialized:
q.page['meta'] = ui.meta_card(box='')
q.page['form'] = ui.form_card(box='1 1 2 1', items=[
ui.button(name='start_job', label='S3 download'),
])
q.client.initialized = True
# Handle start job button click.
if q.args.start_job:
q.page['meta'].dialog = ui.dialog(title='Blocking job', blocking=True, items=[
ui.progress(label='Progress', value=0),
])
# Get the current event loop to update UI later.
loop = asyncio.get_event_loop()
with concurrent.futures.ThreadPoolExecutor() as pool:
await q.exec(pool, download, q, loop)
# Unimportant, just handle notification dismissal.
if q.events.success_notification and q.events.success_notification.dismissed:
q.page['meta'].notification_bar = None
await q.page.save()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment