render_agentic_demo.py
1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 """Render examples/agentic_demo.html to docs/figs/agentic-demo.png. 4 5 Uses Playwright's headless Chromium to capture a single full-page 6 screenshot at viewport width 1200px (matching the demo's 1180px max 7 container width), with the top CAPTURE toolbar hidden via the 8 ``body.capture`` CSS class. 9 10 Re-run this any time ``examples/agentic_demo.html`` changes so the 11 figure at ``docs/figs/agentic-demo.png`` (rendered on readthedocs via 12 ``docs/examples/agentic.rst``) stays in sync with the HTML source. 13 14 Prerequisites (one-time): 15 16 .. code-block:: bash 17 18 pip install playwright 19 playwright install chromium 20 21 Usage: 22 23 .. code-block:: bash 24 25 python scripts/render_agentic_demo.py 26 """ 27 from __future__ import annotations 28 29 import sys 30 from pathlib import Path 31 32 REPO = Path(__file__).resolve().parents[1] 33 HTML = REPO / "examples" / "agentic_demo.html" 34 PNG = REPO / "docs" / "figs" / "agentic-demo.png" 35 36 37 def main() -> int: 38 try: 39 from playwright.sync_api import sync_playwright 40 except ImportError: 41 print( 42 "playwright is not installed. Run:\n" 43 " pip install playwright\n" 44 " playwright install chromium", 45 file=sys.stderr, 46 ) 47 return 1 48 49 if not HTML.is_file(): 50 print(f"ERROR: {HTML} not found", file=sys.stderr) 51 return 1 52 53 PNG.parent.mkdir(parents=True, exist_ok=True) 54 55 with sync_playwright() as pw: 56 browser = pw.chromium.launch() 57 context = browser.new_context( 58 viewport={"width": 1200, "height": 900}, 59 device_scale_factor=2, # retina-sharp for docs 60 ) 61 page = context.new_page() 62 page.goto(HTML.as_uri()) 63 # Hide the top CAPTURE toolbar so it does not appear in the PNG. 64 # The HTML wires this up via the `body.capture` class selector. 65 page.evaluate("document.body.classList.add('capture')") 66 # Wait for layout and web fonts to settle before capturing. 67 page.wait_for_load_state("networkidle") 68 # `full_page=True` captures the entire scroll height as a single 69 # PNG, so there is no need to stitch multiple screenshots. 70 page.screenshot(path=str(PNG), full_page=True) 71 browser.close() 72 73 size_kb = PNG.stat().st_size / 1024 74 print(f"Wrote {PNG.relative_to(REPO)} ({size_kb:.0f} KB)") 75 return 0 76 77 78 if __name__ == "__main__": 79 sys.exit(main())