Add per-request cross_check toggle to the HTTP service (lazy-loaded)
POST /remove-background gains an optional cross_check form field (1/0/true/false/yes/no/on/off; empty = service default). The effective state is reported in the X-BGFilter-Cross-Check response header. The cross-check model is now never preloaded at startup: the first request that enables it pays the one-time load (measured ~8 s on top of the ~50 s cc inference), after which the instance is cached and shared. Verified with a functional test against PipelineManager: cc-off requests never load the model, cc=1 lazy-loads then reuses the cached instance, and omitting the field falls back to the service default. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -129,6 +129,20 @@ def _normalize_seg_model(value: str | None) -> str | None:
|
||||
return v
|
||||
|
||||
|
||||
def _normalize_cross_check(value: str | None) -> bool | None:
|
||||
"""None/empty -> use the service default; otherwise a boolean string."""
|
||||
if value is None:
|
||||
return None
|
||||
v = value.strip().lower()
|
||||
if v == "":
|
||||
return None
|
||||
if v in ("1", "true", "yes", "on"):
|
||||
return True
|
||||
if v in ("0", "false", "no", "off"):
|
||||
return False
|
||||
raise HTTPException(status_code=400, detail="invalid cross_check")
|
||||
|
||||
|
||||
def _decode_image(data: bytes) -> np.ndarray:
|
||||
if not data:
|
||||
raise HTTPException(status_code=400, detail="empty image")
|
||||
@@ -162,12 +176,15 @@ async def remove_background(
|
||||
file: UploadFile = File(...),
|
||||
screen_color: str | None = Form(None),
|
||||
seg_model: str | None = Form(None),
|
||||
cross_check: str | None = Form(None),
|
||||
):
|
||||
if _manager is None:
|
||||
raise HTTPException(status_code=503, detail="service not ready")
|
||||
|
||||
normalized_color = _normalize_screen_color(screen_color)
|
||||
normalized_seg = _normalize_seg_model(seg_model) or _manager.default_seg_model
|
||||
normalized_cc = _normalize_cross_check(cross_check)
|
||||
effective_cc = normalized_cc if normalized_cc is not None else _manager.cross_check_enabled
|
||||
|
||||
rgb = _decode_image(await file.read())
|
||||
|
||||
@@ -178,7 +195,10 @@ async def remove_background(
|
||||
result = await loop.run_in_executor(
|
||||
None,
|
||||
lambda: _manager.process(
|
||||
rgb, screen_color=normalized_color, seg_model=normalized_seg
|
||||
rgb,
|
||||
screen_color=normalized_color,
|
||||
seg_model=normalized_seg,
|
||||
cross_check=normalized_cc,
|
||||
),
|
||||
)
|
||||
except RuntimeError as exc:
|
||||
@@ -200,5 +220,6 @@ async def remove_background(
|
||||
"X-BGFilter-Elapsed-Ms": str(elapsed_ms),
|
||||
"X-BGFilter-Seg-Model": normalized_seg,
|
||||
"X-BGFilter-Screen-Color": normalized_color if normalized_color else "auto",
|
||||
"X-BGFilter-Cross-Check": "on" if effective_cc else "off",
|
||||
}
|
||||
return Response(content=png, media_type="image/png", headers=headers)
|
||||
|
||||
Reference in New Issue
Block a user