```
import asyncio
from logging import getLogger
from uuid import uuid4
from PIL import Image
import flet as ft

from utils.clipcrop import CropClip
from configs.path_config import EXAMPLE_IMAGE, OUTPUT_DIR
from configs.logging_config import LOGGING_CONFIG
from logging.config import dictConfig

# ログ設定
dictConfig(LOGGING_CONFIG)
logger = getLogger(__name__)

class AsyncPipeline:
    def __init__(self, clip_cls, num_workers=1):
        self.clip_cls = clip_cls
        self.num_workers = num_workers
        self.queue = asyncio.Queue()
        self.results = {}
        self.task_id_map = {}
        self.futures = {}
        self.workers = []

    async def _worker(self, name: str):
        with self.clip_cls() as cc:
            logger.info(f"Worker {name} initialized.")
            while True:
                try:
                    task = await self.queue.get()
                    if task is None:
                        self.queue.task_done()
                        break  # Shutdown signal
                    task_id, img, prompt = task
                    logger.info(f"{name} started {task_id}")
                    try:
                        result = await asyncio.to_thread(cc.clip_clop, img, prompt)
                        self.results[task_id] = result
                        self.futures[task_id].set_result(result)
                    except Exception as e:
                        logger.exception(f"Exception in {name} for task {task_id}")
                        self.results[task_id] = e
                        self.futures[task_id].set_exception(e)
                    finally:
                        self.queue.task_done()
                except asyncio.CancelledError:
                    break

    async def start_workers(self):
        self.workers = [asyncio.create_task(self._worker(f"worker-{i}")) for i in range(self.num_workers)]

    async def submit_task(self, name, prompt, img_path):
        with Image.open(img_path) as img:
            img.load()
        task_id = str(uuid4())
        self.task_id_map[task_id] = name
        future = asyncio.get_running_loop().create_future()
        self.futures[task_id] = future
        await self.queue.put((task_id, img, prompt))
        return task_id, future

    async def stop(self):
        for _ in self.workers:
            await self.queue.put(None)  # Signal shutdown
        await self.queue.join()
        for w in self.workers:
            w.cancel()
        await asyncio.gather(*self.workers, return_exceptions=True)

# Flet UI 定義
async def main_ui_async(page: ft.Page):
    page.title = "Async Image Pipeline"
    status_list = ft.ListView(expand=True, spacing=5, padding=10)
    pipeline = AsyncPipeline(CropClip, num_workers=2)

    await pipeline.start_workers()

    async def handle_click(e):
        # ボタンがクリックされたらタスクを3つ投入
        tasks = {
            'girl': ('a girl', EXAMPLE_IMAGE),
            'clock': ('a clock on the wall', EXAMPLE_IMAGE),
            'teddy': ('a teddy bear', EXAMPLE_IMAGE),
        }
        for name, (prompt, img_path) in tasks.items():
            task_id, future = await pipeline.submit_task(name, prompt, img_path)
            status_list.controls.append(ft.Text(f"Task {name} ({task_id[:6]}) submitted."))
            page.update()

            async def await_result(task_id=task_id, name=name, future=future):
                try:
                    result = await future
                    if isinstance(result, Image.Image):
                        out_path = OUTPUT_DIR / f"ui_output_{name}_{task_id[:6]}.png"
                        result.save(out_path)
                        status_list.controls.append(ft.Text(f"✅ Task {name} completed. Saved to {out_path}"))
                    else:
                        status_list.controls.append(ft.Text(f"❌ Task {name} failed with error: {result}"))
                except Exception as e:
                    status_list.controls.append(ft.Text(f"❌ Task {name} failed: {e}"))
                page.update()

            asyncio.create_task(await_result())

    # Fletの同期イベント内で非同期処理を安全に呼ぶためのラッパー
    def on_click(e):
        asyncio.create_task(handle_click(e))

    run_button = ft.ElevatedButton("Run Tasks", on_click=on_click)
    page.add(run_button, status_list)

ft.app(target=main_ui_async)
```

```
C:\Users\faker\Desktop\lora_test\.venv\Scripts\python.exe C:\Users\faker\Desktop\lora_test\src\test.py 
2025-06-14 19:38:30,015 flet:371 __get_assets_dir_path [INFO]: Assets path configured: C:\Users\faker\Desktop\lora_test\src\assets
2025-06-14 19:38:30,017 flet:61 start [INFO]: Starting up TCP server on localhost:59004
2025-06-14 19:38:30,026 flet:171 app_async [INFO]: Flet app has started...
2025-06-14 19:38:30,030 flet:131 on_app_startup [INFO]: App URL: tcp://localhost:59004
2025-06-14 19:38:30,030 flet_desktop:62 __locate_and_unpack_flet_view [INFO]: Starting Flet View app...
2025-06-14 19:38:30,033 flet_desktop:86 __locate_and_unpack_flet_view [INFO]: Looking for Flet executable at: C:\Users\faker\Desktop\lora_test\.venv\Lib\site-packages\flet_desktop\app\flet\flet.exe
2025-06-14 19:38:30,033 flet_desktop:88 __locate_and_unpack_flet_view [INFO]: Flet View found in: C:\Users\faker\Desktop\lora_test\.venv\Lib\site-packages\flet_desktop\app\flet\flet.exe
2025-06-14 19:38:30,537 flet:240 on_session_created [INFO]: App session started
2025-06-14 19:38:30,539 utils.clipcrop:242 load [INFO]: YOLOモデルをロードしています...
2025-06-14 19:38:31,757 utils.clipcrop:246 load [INFO]: CLIPモデルをロードしています...
2025-06-14 19:38:35,202 __main__:28 _worker [INFO]: Worker worker-0 initialized.
2025-06-14 19:38:35,202 utils.clipcrop:242 load [INFO]: YOLOモデルをロードしています...
2025-06-14 19:38:35,277 utils.clipcrop:246 load [INFO]: CLIPモデルをロードしています...
2025-06-14 19:38:38,862 __main__:28 _worker [INFO]: Worker worker-1 initialized.
2025-06-14 19:38:40,077 asyncio:1820 default_exception_handler [ERROR]: Future exception was never retrieved
future: <Future finished exception=RuntimeError('no running event loop')>
Traceback (most recent call last):
  File "C:\Users\faker\AppData\Local\Programs\Python\Python312\Lib\concurrent\futures\thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\faker\Desktop\lora_test\.venv\Lib\site-packages\flet\core\page.py", line 906, in wrapper
    handler(*args)
  File "C:\Users\faker\Desktop\lora_test\src\test.py", line 108, in on_click
    asyncio.create_task(handle_click(e))
  File "C:\Users\faker\AppData\Local\Programs\Python\Python312\Lib\asyncio\tasks.py", line 417, in create_task
    loop = events.get_running_loop()
           ^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: no running event loop
C:\Users\faker\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py:1987: RuntimeWarning: coroutine 'main_ui_async.<locals>.handle_click' was never awaited
  handle = None  # Needed to break cycles when an exception occurs.
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

Process finished with exit code 0
```