| """The storage pipeline must produce a picture's embedding AND breed from ONE model pass when the |
| embedder and breed classifier are the same HF model (spec §9.1). Also covers the mock fallback.""" |
| import numpy as np |
| from sqlalchemy import select |
|
|
| from app.db import SessionLocal |
| from app.models import BreedPrediction, Embedding, KnownDog, User |
| from app.models.base import SubjectType, UserRole |
| from app.security import hash_password |
| from app.services import images as images_svc |
| from app.services.images import embed_and_breed_picture, process_and_store_picture |
|
|
|
|
| def _img(seed): |
| from scripts.make_sample_images import make_image |
|
|
| return make_image(seed) |
|
|
|
|
| def _make_known_picture(db): |
| user = User(name="O", email="o@example.com", zip="20001", |
| password_hash=hash_password("password123"), role=UserRole.owner) |
| db.add(user) |
| db.flush() |
| dog = KnownDog(owner_id=user.id, name="Rex", description="") |
| db.add(dog) |
| db.flush() |
| |
| pic = process_and_store_picture( |
| db, subject_type=SubjectType.known, subject_id=dog.id, data=_img(101), |
| generate_embedding=False, generate_breed=False, |
| ) |
| db.commit() |
| return pic |
|
|
|
|
| def test_mock_fallback_writes_both_and_is_idempotent(): |
| db = SessionLocal() |
| try: |
| pic = _make_known_picture(db) |
| emb, breed = embed_and_breed_picture(db, pic, skip_if_exists=True) |
| db.commit() |
| assert emb and breed |
| assert db.execute( |
| select(Embedding).where(Embedding.picture_id == pic.id) |
| ).first() is not None |
| assert db.execute( |
| select(BreedPrediction).where(BreedPrediction.picture_id == pic.id) |
| ).first() is not None |
| |
| again = embed_and_breed_picture(db, pic, skip_if_exists=True) |
| assert again == (False, False) |
| finally: |
| db.close() |
|
|
|
|
| class _FakeHFEmbedder: |
| """Stands in for HFEmbedder: records how many times the model 'forward' runs.""" |
| name = "hf-embed" |
| version = "Fake-Model" |
| dim = 4 |
| calls = 0 |
|
|
| def embed_and_breed(self, paths, top_k): |
| type(self).calls += 1 |
| vec = np.ones(self.dim, dtype=np.float32) / 2.0 |
| labels = [("border collie", 0.9), ("kelpie", 0.1)][:top_k] |
| return [(vec, labels) for _ in paths] |
|
|
|
|
| def test_same_hf_model_runs_the_model_once_for_both(monkeypatch): |
| db = SessionLocal() |
| try: |
| pic = _make_known_picture(db) |
|
|
| |
| monkeypatch.setattr(images_svc.settings, "embedder", "hf", raising=False) |
| monkeypatch.setattr(images_svc.settings, "breed_classifier", "hf", raising=False) |
| monkeypatch.setattr(images_svc.settings, "embedder_hf_model", "x/Fake-Model", raising=False) |
| monkeypatch.setattr(images_svc.settings, "breed_model", "x/Fake-Model", raising=False) |
| monkeypatch.setattr(images_svc.settings, "breed_top_k", 2, raising=False) |
| fake = _FakeHFEmbedder() |
| monkeypatch.setattr(images_svc, "get_embedder", lambda: fake) |
|
|
| emb, breed = embed_and_breed_picture(db, pic, skip_if_exists=False) |
| db.commit() |
|
|
| assert emb and breed |
| assert _FakeHFEmbedder.calls == 1 |
|
|
| |
| e = db.execute( |
| select(Embedding).where( |
| Embedding.picture_id == pic.id, Embedding.model_name == "hf-embed" |
| ) |
| ).scalar_one() |
| assert e.dim == 4 |
| breeds = db.execute( |
| select(BreedPrediction).where( |
| BreedPrediction.picture_id == pic.id, |
| BreedPrediction.model_name == "hf-breed", |
| BreedPrediction.model_version == "Fake-Model", |
| ) |
| ).scalars().all() |
| assert [b.label for b in breeds] == ["border collie", "kelpie"] |
| finally: |
| db.close() |
|
|