Skip to content

Replace headless Chromium HTML rendering with a WeasyPrint subprocess #45

@Rustam-Z

Description

@Rustam-Z

Summary

Swap the current render_html implementation — which renders an HTML snippet to PNG via headless Chromium — for a subprocess calling WeasyPrint.

Motivation

Headless Chromium is heavy for what the harness actually needs:

  • ~300MB+ Chromium binary bundled/installed on the VPS.
  • High cold-start cost and memory footprint per render.
  • Overkill when the rendered content is static (tables, charts, diagrams).

WeasyPrint is a pure-Python HTML/CSS rendering engine (backed by Pango/cairo). Running it in a subprocess keeps the render isolated from the main process and avoids the browser entirely — much lighter, faster startup, lower memory. A good fit for a small VPS.

Proposed change

  • Replace the Chromium render path with a subprocess that invokes WeasyPrint on the HTML snippet and writes a PNG to data/renders/.
  • Subprocess isolation: a bad render can't take down the harness; enforce a timeout.
  • Keep the render_html MCP tool signature unchanged (html, width, height, title) so nothing upstream breaks.

Trade-off to confirm before implementing

WeasyPrint does not execute JavaScript. The current setup can run inline JS libs (Chart.js, D3). After this change:

  • Pure HTML/CSS + inline SVG renders → fine. The render-style skill is already CSS/SVG-only, and recent charts were hand-built SVG — these keep working.
  • Any render relying on a JS charting lib → would break and must be rebuilt as static SVG/CSS.

If dropping JS rendering is acceptable (it looks like it is, given current usage), WeasyPrint is a clean win. Flagging it so the decision is explicit.

Notes

  • WeasyPrint needs system libs (Pango, cairo, gdk-pixbuf) — a deployment/Dockerfile change.
  • Confirm WeasyPrint's PNG output path; it's PDF-first, PNG is supported but worth verifying the quality/DPI is acceptable for Telegram photos.

Requested by the owner.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions