photo-classification / tests /test_integration_real_clip.py
esandorfi's picture
Domain features first reorganisation
68f48a7
from __future__ import annotations
import base64
import io
import pytest
from PIL import Image
from fastapi.testclient import TestClient
from api.app import build_app
from api.model.clip_store import ClipStore
from api.classify.service import TwoStageClassifier
@pytest.mark.integration
def test_real_clip_smoke():
# Build real app (loads CLIP on first use)
try:
store = ClipStore()
except Exception as e:
pytest.skip(f"CLIP unavailable: {e}")
classifier = TwoStageClassifier(store=store)
app = build_app(store=store, classifier=classifier)
client = TestClient(app)
# Upload a minimal label set
label_set = {
"name": "integration-v1",
"domains": [
{"id": "scene", "display": "Scene", "prompt": "a photo of a place or landscape"},
{"id": "document", "display": "Document", "prompt": "a photo of a document or paper"},
],
"labels_by_domain": {
"scene": [
{"id": "scene.city", "display": "City", "prompt": "a city street scene photo"},
{"id": "scene.nature", "display": "Nature", "prompt": "a nature landscape photo"},
],
"document": [
{"id": "doc.page", "display": "Document page", "prompt": "a photo of a printed document page"},
],
},
}
r = client.post("/api/v1/label-sets", json=label_set)
assert r.status_code == 200
label_set_hash = r.json()["label_set_hash"]
# Build a tiny white image
img = Image.new("RGB", (32, 32), (255, 255, 255))
buf = io.BytesIO()
img.save(buf, format="PNG")
image_b64 = base64.b64encode(buf.getvalue()).decode("utf-8")
# Classify with explicit hash
r2 = client.post(
f"/api/v1/classify?label_set_hash={label_set_hash}",
json={"image_base64": image_b64, "domain_top_n": 1, "top_k": 2},
)
assert r2.status_code == 200
data = r2.json()
assert data["label_set_hash"] == label_set_hash
assert "domain_hits" in data and len(data["domain_hits"]) == 1
assert "elapsed_ms" in data