""" Generate expected Recipe models from saved HTML snapshots (offline). Reads HTML files from tests/sample_files/recipes and writes expected Recipe JSONs into tests/sample_files/recipes/expected with matching slugs. Run: python -m scripts.generate_expected_from_snapshots """ import json from pathlib import Path from typing import Optional from types import SimpleNamespace from db import connect, create from recipes import parse_recipe_from_html SNAP_DIR = Path("tests/sample_files/recipes") def _write_expected(slug: str, recipe) -> None: # Write .recipe.json at SNAP_DIR root (canonical) new_out = SNAP_DIR / f"{slug}.recipe.json" if recipe is None: new_out.write_text("null") else: new_out.write_text(recipe.model_dump_json(by_alias=True, indent=2)) async def _run() -> None: html_files = sorted(p for p in SNAP_DIR.glob("*.html")) if not html_files: print("no HTML snapshots found; run scripts.save_recipe_pages first") return # Minimal created_by object the parser expects (id, display_name) created_by = SimpleNamespace(id=1, display_name="Snapshot Generator") conn = await connect() await create(conn) try: for p in html_files: slug = p.stem url = None meta_path = SNAP_DIR / f"{slug}.meta.json" if meta_path.exists(): try: meta = json.loads(meta_path.read_text()) url = meta.get("final_url") or meta.get("url") except Exception: pass base_url = url or slug html = p.read_text() recipe = await parse_recipe_from_html(conn, created_by, base_url, html) _write_expected(slug, recipe) print(f"wrote expected for {slug}: {'ok' if recipe else 'none'}") finally: await conn.close() if __name__ == "__main__": import asyncio asyncio.run(_run())