From afdbbd5e19690b7e34b75e8ca3253d35b8dcbde7 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 7 Feb 2026 02:57:25 +0100 Subject: [PATCH] feat: add pytest-asyncio to requirements and update CI to install it; refactor geninfo parsing logic --- .github/workflows/ci-python.yml | 2 +- backend/features/metadata/service.py | 26 ++++++++++++++------------ requirements.txt | 3 +++ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index 033bba03..b7bd9746 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -22,7 +22,7 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt - pip install pytest + pip install pytest pytest-asyncio - name: Run tests run: | python -m pytest -q diff --git a/backend/features/metadata/service.py b/backend/features/metadata/service.py index b8385bdf..e5cbfc47 100644 --- a/backend/features/metadata/service.py +++ b/backend/features/metadata/service.py @@ -186,27 +186,29 @@ class MetadataService: async def _enrich_with_geninfo_async(self, combined: Dict[str, Any]) -> None: """Helper to parse geninfo from prompt/workflow in combined metadata (Worker Thread).""" + prompt_graph = combined.get("prompt") + workflow = combined.get("workflow") + loop = asyncio.get_running_loop() + geninfo_res = None + try: - prompt_graph = combined.get("prompt") - workflow = combined.get("workflow") - loop = asyncio.get_running_loop() # Offload heavy parsing to thread pool to prevent blocking the event loop geninfo_res = await loop.run_in_executor( None, functools.partial(parse_geninfo_from_prompt, prompt_graph, workflow=workflow) ) - - if geninfo_res.ok and geninfo_res.data: - combined["geninfo"] = geninfo_res.data - elif "geninfo" not in combined: - gi = _build_geninfo_from_parameters(combined) - # Always set geninfo to a dict (empty if nothing parsed) - combined["geninfo"] = gi if gi is not None else {} - if not gi and _looks_like_media_pipeline(prompt_graph): - combined["geninfo_status"] = {"kind": "media_pipeline", "reason": "no_sampler"} except Exception as exc: logger.debug(f"GenInfo parse skipped: {exc}") + if geninfo_res and geninfo_res.ok and geninfo_res.data: + combined["geninfo"] = geninfo_res.data + elif "geninfo" not in combined: + gi = _build_geninfo_from_parameters(combined) + # Always set geninfo to a dict (empty if nothing parsed) + combined["geninfo"] = gi if gi is not None else {} + if not gi and _looks_like_media_pipeline(prompt_graph): + combined["geninfo_status"] = {"kind": "media_pipeline", "reason": "no_sampler"} + async def _resolve_probe_mode(self, override: Optional[str]) -> str: if isinstance(override, str): normalized = override.strip().lower() diff --git a/requirements.txt b/requirements.txt index a9b01337..6ae5ee26 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,3 +22,6 @@ pywin32>=300; sys_platform == 'win32' # Note: tkinter is required for native folder browser functionality # tkinter is included in standard Python distribution but may be missing in minimal installs + +# Testing helpers +pytest-asyncio>=0.22.0