fix(fc2b): lazy-import onnxruntime in tagger (CI collection failure)

onnxruntime is in requirements-ml.txt only (deliberately kept out of the
lean web image and CI). The top-level `import onnxruntime` broke pytest
collection of test_ml_tagger / test_ml_suggestions / test_tasks_ml even
though those are pure-logic/integration-marked, because collection
imports the module.

Mirrors the embedder's lazy-torch pattern: onnxruntime is imported inside
Tagger.load(), placed AFTER the file-existence checks so
test_load_raises_when_model_missing still gets RuntimeError (not
ModuleNotFoundError) in onnxruntime-less environments. self._session
annotation dropped to a comment to avoid an eval-time ort reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 10:15:24 -04:00
parent 4623551bf6
commit 4ebe779b7c
+11 -2
View File
@@ -15,9 +15,13 @@ from dataclasses import dataclass
from pathlib import Path from pathlib import Path
import numpy as np import numpy as np
import onnxruntime as ort
from PIL import Image, ImageFile from PIL import Image, ImageFile
# onnxruntime lives in requirements-ml.txt only — it is NOT installed in the
# lean web image or in CI. Imported lazily inside Tagger.load() so this module
# imports fine without it (the suggestion service imports SURFACED_CATEGORIES
# from here in the web container, and CI collects the pure-logic tests).
# Tolerate minutely-truncated source images (same rationale as IR's wd14.py: # Tolerate minutely-truncated source images (same rationale as IR's wd14.py:
# a few missing bytes at the JPEG EOI shouldn't block tagging the whole image). # a few missing bytes at the JPEG EOI shouldn't block tagging the whole image).
ImageFile.LOAD_TRUNCATED_IMAGES = True ImageFile.LOAD_TRUNCATED_IMAGES = True
@@ -43,7 +47,7 @@ class TagPrediction:
class Tagger: class Tagger:
def __init__(self, model_dir: Path | None = None): def __init__(self, model_dir: Path | None = None):
self._model_dir = model_dir or _MODEL_DIR self._model_dir = model_dir or _MODEL_DIR
self._session: ort.InferenceSession | None = None self._session = None # onnxruntime.InferenceSession once load()ed
self._tag_meta: list[dict] | None = None self._tag_meta: list[dict] | None = None
self._input_name: str | None = None self._input_name: str | None = None
self._output_name: str | None = None self._output_name: str | None = None
@@ -73,6 +77,11 @@ class Tagger:
{"name": row["name"], "category": row["category"]} {"name": row["name"], "category": row["category"]}
) )
# Lazy import — kept after the file-existence checks so the
# missing-model RuntimeError still fires first in environments
# without onnxruntime (CI / lean web image).
import onnxruntime as ort
session = ort.InferenceSession( session = ort.InferenceSession(
str(model_path), providers=["CPUExecutionProvider"] str(model_path), providers=["CPUExecutionProvider"]
) )