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>
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user