Async apps

nØthing spec¡al by Jimsjoo·2024년 4월 17일

Flet

목록 보기
6/8

Flet 앱은 비동기 앱으로 작성할 수 있으며 asyncio 및 기타 Python 비동기 라이브러리를 사용할 수 있다. 코루틴 호출은 Flet에서 자연스럽게 지원되므로 동기적으로 실행하기 위해 코루틴(coroutine)을 래핑할 필요가 없다.
기본적으로 Flet은 별도의 스레드에서 컨트롤 이벤트 핸들러를 실행하지만, 때로는 비효율적으로 CPU를 사용하거나 HTTP 응답을 기다리거나 sleep()을 실행하는 동안 아무 작업도 하지 않을 수 있다.
반면 asyncio는 '코루틴' 간에 실행 컨텍스트를 전환하여 단일 스레드에서 동시성을 구현할 수 있다. 이는 Pyodide를 사용하여 정적 웹사이트로 게시하려는 앱에 특히 중요하다. Pyodide는 웹어셈블리(WASM)로 빌드되어 브라우저에서 실행되는 Python 런타임이다.

Getting started with async

Flet앱의 main함수에 async를 붙여 asyncio API를 사용할 수 있다.

import flet as ft

async def main(page: ft.Page):
    await asyncio.sleep(1)
    page.add(ft.Text("Hello, async world!"))

ft.app(main)

Control event handlers

이벤트핸들러는 동기 또는 비동기가 될 수 있다.

def page_resize(e):
    print("New page size:", page.window_width, page.window_height)

page.on_resize = page_resize

핸들러가 비동기함수를 사용한다면 비동기가 된다.

async def main(page: ft.Page):

    async def button_click(e):
        await some_async_method()
        page.add(ft.Text("Hello!"))

    page.add(ft.ElevatedButton("Say hello!", on_click=button_click))

ft.app(main)

Async lambdas

비동기 lambda함수라는 건 없다. 비동기앱에서 람다이벤트핸들러는 가질 수 있다.

page.on_error = lambda e: print("Page error:", e.data)

Sleeping

비동기 앱에서 코드실행을 지연하려면 ascyncio.sleep를 사용해야 한다.

import asyncio
import flet as ft

def main(page: ft.Page):
    async def button_click(e):
        await asyncio.sleep(1)
        page.add(ft.Text("Hello!"))

    page.add(
        ft.ElevatedButton("Say hello with delay!", on_click=button_click)
    )

ft.app(main)

Threading

백그라운드로 뭔가 실행하려면 pahe.run_task()를 사용한다. 예를 들어 백그라운드로 스스로 자신을 업데이트하는 Countdown커스텀 컨트톨을 다음과 같이 구현할 수 있다.

import asyncio
import flet as ft

class Countdown(ft.Text):
    def __init__(self, seconds):
        super().__init__()
        self.seconds = seconds

    def did_mount(self):
        self.running = True
        self.page.run_task(self.update_timer)

    def will_unmount(self):
        self.running = False

    async def update_timer(self):
        while self.seconds and self.running:
            mins, secs = divmod(self.seconds, 60)
            self.value = "{:02d}:{:02d}".format(mins, secs)
            self.update()
            await asyncio.sleep(1)
            self.seconds -= 1

def main(page: ft.Page):
    page.add(Countdown(120), Countdown(60))

ft.app(main)

profile
harmonized or torn between programming and finance

0개의 댓글