Project Plan
Goal
A lightweight internal HTTP service that converts HTML to PDF, suitable for use across all Systaro products and internal tooling. Callers send HTML (with public URL or inline assets) and receive a PDF.
Status
Phase 1 — MVP ✅ Done
Phases
Phase 1 — MVP (done)
- [x] FastAPI service with
/renderendpoint - [x] WeasyPrint integration
- [x]
asset://scheme for inline asset injection - [x] Public URL passthrough (WeasyPrint fetches directly)
- [x] PDF/A variant support
- [x] Docker + docker-compose setup
- [x] API reference, getting started, and page-break documentation
Phase 2 — Hardening
- [ ] Request size limits (HTML, total payload)
- [ ] Per-render timeout (configurable, default 30s)
- [ ] Structured error responses (distinguish render failures from bad input)
- [ ] Request logging with render time + output size
- [ ]
/metricsendpoint (Prometheus-compatible) - [ ] Integration into internal CI smoke test
Phase 3 — Features
- [ ] Async rendering mode:
POST /render/asyncreturnsjob_id, pollGET /jobs/{id} - [ ] Header injection (add consistent Systaro branding across all renders)
- [ ] Font bundle support (send custom fonts as assets)
- [ ] Watermark option in render options
- [ ] PDF merge: accept multiple HTML documents, return single PDF
Phase 4 — Scale (if needed)
- [ ] Worker pool with configurable concurrency
- [ ] Redis-backed job queue for async mode
- [ ] Kubernetes deployment manifests
- [ ] Per-caller rate limiting via API key header
- [ ] S3 output option (return presigned URL instead of streaming bytes)
Non-Goals
- JavaScript execution in templates (intentional — callers pre-render dynamic content server-side)
- XFA / AcroForm form filling
- PDF editing or manipulation of existing PDFs
- Image format conversion
Known Limitations
- WeasyPrint is single-threaded per render. Concurrent requests each spin a separate process. Under heavy load, add more replicas rather than threads.
- No JS execution. Charts, graphs, or dynamic content must be rendered server-side before sending HTML (e.g. pre-rendered SVG, or server-side Chart.js via canvas).
- Font rendering depends on fonts installed in the Docker image. Custom fonts should be sent as
asset://references.