Spaces:
Running
Running
| """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() | |