Files
upbeatBytes/scripts/art_blurb_palette_backfill.py
T
thejayman77 ed814c97b9 Daily Art engine: museum-guide blurb (grounded LLM) + extracted palette
- daily_art gains blurb + palette columns (idempotent migration).
- art._palette: Pillow median-cut to ~5 hex colors from the cached image (best-
  effort → [] on any failure). art._blurb: a warm 2-3 sentence "what you're
  looking at" note grounded in the Met catalogue (title/artist/bio/date/medium/
  classification/culture/tags). Prompt leans on context/significance and the
  title+tags for subject — explicitly NOT asserting literal composition (figure
  counts/poses) it can't see, since the model can't view the image. Markdown
  stripped from the output.
- pick_daily generates both (client optional → blurb skipped when absent); cycle
  + art CLI pass an LLM client. /api/art/today exposes blurb + palette.
- Backfilled the last 3 days on host (Veteran / Magnolia Vase / Bierstadt).
- scripts/art_blurb_palette_backfill.py for in-place backfill (no re-pick).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 20:12:54 -04:00

35 lines
1.5 KiB
Python

"""One-off: migrate daily_art (blurb/palette) and backfill the most recent picks in place
— re-fetch Met metadata for the guide blurb, extract the palette from the cached image —
WITHOUT re-picking (keeps each day's existing piece). Run on the host with LLM env sourced."""
import json
import os
from goodnews import art
from goodnews.db import connect, init_db
from goodnews.llm import LocalModelClient
conn = connect(os.environ.get("GOODNEWS_DB", "data/goodnews.sqlite3"))
init_db(conn) # idempotent migration: adds blurb/palette
client = LocalModelClient.from_env()
rows = conn.execute(
"SELECT art_date, object_id, image_file, title FROM daily_art "
"WHERE blurb IS NULL OR palette IS NULL ORDER BY art_date DESC LIMIT 8"
).fetchall()
print(f"rows to backfill: {len(rows)}")
for r in rows:
img = art.cache_dir() / r["image_file"] if r["image_file"] else None
palette = json.dumps(art._palette(img)) if (img and img.exists()) else "[]"
blurb = None
try:
blurb = art._blurb(client, art._object(r["object_id"]))
except Exception as exc: # noqa: BLE001
print(f" blurb fetch failed for {r['object_id']}: {exc}")
conn.execute("UPDATE daily_art SET blurb=COALESCE(?, blurb), palette=? WHERE art_date=?",
(blurb, palette, r["art_date"]))
conn.commit()
print(f"\n{r['art_date']} · #{r['object_id']} · {r['title']}")
print(f" palette: {palette}")
print(f" blurb: {blurb}")
conn.close()