comic-panel-search / src /pinecone /upsert_panels.py
lukkawolff's picture
streamlit app
830fbdc
Raw
History Blame Contribute Delete
2.53 kB
"""Upsert comic panel documents into Pinecone."""
import json
import os
import time
from pathlib import Path
from pinecone import Pinecone
INDEX_NAME = os.environ.get("PINECONE_INDEX_NAME", "comic-panels")
NAMESPACE = os.environ.get("PINECONE_NAMESPACE", "comics-v1")
DOCS_PATH = Path("data/comics/processed/pinecone_documents.jsonl")
BATCH_SIZE = 100
def batched_jsonl(path: Path, batch_size: int = BATCH_SIZE):
batch = []
with open(path) as f:
for line in f:
batch.append(json.loads(line))
if len(batch) >= batch_size:
yield batch
batch = []
if batch:
yield batch
def upsert_with_retry(index, batch: list, retries: int = 5):
for attempt in range(retries):
try:
return index.documents.upsert(namespace=NAMESPACE, documents=batch)
except Exception as exc:
if attempt == retries - 1:
raise
wait = 2 ** attempt
print(f" Upsert attempt {attempt + 1} failed: {exc}; retrying in {wait}s")
time.sleep(wait)
def validate_search(index) -> None:
"""Quick sanity check: run a dense search after upsert."""
import random
dummy_vector = [random.gauss(0, 1) for _ in range(int(os.environ.get("IMAGE_EMBED_DIM", "512")))]
norm = sum(x ** 2 for x in dummy_vector) ** 0.5
dummy_vector = [x / norm for x in dummy_vector]
results = index.documents.search(
namespace=NAMESPACE,
top_k=3,
score_by=[{"type": "dense_vector", "field": "image_dense", "values": dummy_vector}],
include_fields=["panel_id", "comic_id", "page_num"],
)
hits = results.matches
print(f"Validation search returned {len(hits)} hits")
for h in hits:
print(f" {h.id} score={h.score:.4f}")
def main():
pc = Pinecone(api_key=os.environ["PINECONE_API_KEY"])
index = pc.preview.index(name=INDEX_NAME)
total = 0
failed_batches = 0
for batch_num, batch in enumerate(batched_jsonl(DOCS_PATH), start=1):
try:
upsert_with_retry(index, batch)
total += len(batch)
if batch_num % 10 == 0:
print(f" Upserted {total} documents...")
except Exception as exc:
failed_batches += 1
print(f" Batch {batch_num} failed permanently: {exc}")
print(f"\nUpsert complete: {total} documents, {failed_batches} failed batches")
if total > 0:
validate_search(index)
if __name__ == "__main__":
main()