Add Vision image fetch failure observability
This commit is contained in:
+21
-1
@@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import logging
|
||||
import time
|
||||
from typing import List, Optional
|
||||
|
||||
import torch
|
||||
@@ -9,7 +11,7 @@ from fastapi import FastAPI, HTTPException, UploadFile, File, Form
|
||||
from pydantic import BaseModel, Field
|
||||
import numpy as np
|
||||
|
||||
from common.image_io import fetch_url_bytes, bytes_to_pil, ImageLoadError
|
||||
from common.image_io import fetch_url_bytes, bytes_to_pil, ImageLoadError, image_url_log_context
|
||||
|
||||
MODEL_NAME = os.getenv("MODEL_NAME", "ViT-B-32")
|
||||
MODEL_PRETRAINED = os.getenv("MODEL_PRETRAINED", "openai")
|
||||
@@ -25,6 +27,7 @@ TAGS: List[str] = [
|
||||
]
|
||||
|
||||
app = FastAPI(title="Skinbase CLIP Service", version="1.0.0")
|
||||
logger = logging.getLogger("clip")
|
||||
|
||||
model, _, preprocess = open_clip.create_model_and_transforms(MODEL_NAME, pretrained=MODEL_PRETRAINED)
|
||||
tokenizer = open_clip.get_tokenizer(MODEL_NAME)
|
||||
@@ -44,6 +47,21 @@ class EmbedRequest(BaseModel):
|
||||
pretrained: Optional[str] = None
|
||||
|
||||
|
||||
def _log_image_load_failure(error: ImageLoadError, url: str, elapsed_ms: float) -> None:
|
||||
fields = {
|
||||
"event": "clip_image_fetch_failed",
|
||||
"stage": error.stage,
|
||||
"error_type": error.category,
|
||||
"exception_class": error.original_exception_class or error.__class__.__name__,
|
||||
"elapsed_ms": round(elapsed_ms, 1),
|
||||
**image_url_log_context(url),
|
||||
}
|
||||
for key in ("remote_status", "content_type"):
|
||||
if key in error.metadata:
|
||||
fields[key] = error.metadata[key]
|
||||
logger.warning("%s", " ".join(f"{key}={value!r}" for key, value in fields.items()))
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
def health():
|
||||
return {"status": "ok", "device": DEVICE, "model": MODEL_NAME, "pretrained": MODEL_PRETRAINED}
|
||||
@@ -143,10 +161,12 @@ async def analyze_file(
|
||||
def embed(req: EmbedRequest):
|
||||
if not req.url:
|
||||
raise HTTPException(400, "url is required")
|
||||
started_at = time.perf_counter()
|
||||
try:
|
||||
data = fetch_url_bytes(req.url)
|
||||
return _embed_image_bytes(data, backend=req.backend, model_name=req.model, pretrained=req.pretrained)
|
||||
except ImageLoadError as e:
|
||||
_log_image_load_failure(e, req.url, (time.perf_counter() - started_at) * 1000)
|
||||
raise HTTPException(400, str(e))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user