Simplz.PDF is a FastAPI service that uses Playwright Chromium to:
- render raw HTML to PDF
- render a remote URL to PDF
- capture a remote URL as a PNG image
The service listens on port 5501 by default.
- Python 3.12 recommended
- Playwright Chromium browser binaries
- Docker Desktop if you want to run the containerized version
Create and activate a virtual environment, then install dependencies:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
playwright install chromiumStart the API locally:
python app.pyAlternatively, run it with Uvicorn directly:
uvicorn wsgi:app --host 0.0.0.0 --port 5501 --workers 1--workers 1 is intentional. The current implementation keeps a shared Playwright browser instance in process.
Service URL:
http://localhost:5501
Build and start the service:
docker compose up -d --buildStop the service:
docker compose downCheck container status:
docker compose psThe container image installs Chromium and the required Playwright system dependencies during build.
For Windows environments, use the bundled deployment script:
.\deploy.ps1The script:
- stops running containers
- rebuilds the image
- starts the service in detached mode
- prints container status
Simple text response used as a basic sanity check.
Example:
curl http://localhost:5501/Health endpoint used by Docker health checks.
Example:
curl http://localhost:5501/healthExpected response:
{"status":"ok"}Generates a small sample PDF to verify Playwright PDF rendering is working.
Example:
curl http://localhost:5501/Test --output test.pdfAccepts raw HTML in the request body and returns a PDF.
Example:
$html = '<html><body><h1>Hello</h1><p>Rendered by Simplz.PDF</p></body></html>'
Invoke-WebRequest -Uri http://localhost:5501/PDF -Method Post -Body $html -ContentType 'text/html; charset=utf-8' -OutFile document.pdfLoads a remote page and returns a PDF.
Query parameters:
dataUrl: required target URL
Optional headers:
Authorization: token value to forward as a bearer tokenlandscape:trueorfalse
Example:
Invoke-WebRequest -Uri 'http://localhost:5501/PDFURL?dataUrl=https://example.com' -OutFile page.pdfExample with forwarded authorization token:
Invoke-WebRequest -Uri 'http://localhost:5501/PDFURL?dataUrl=https://example.com' -Headers @{ Authorization = 'your-token' } -OutFile protected.pdfNote: the service currently forwards the header as Bearer <token> when requesting the target page.
Loads a remote page and returns a PNG screenshot.
Query parameters:
dataUrl: required target URL
Optional headers:
Authorization: token value to forward as a bearer token
Example:
Invoke-WebRequest -Uri 'http://localhost:5501/PDFToImage?dataUrl=https://example.com' -OutFile screenshot.pngIf you want to run the API directly on a Linux host without Docker, a systemd service is the simplest option.
Create a unit file:
sudo nano /etc/systemd/system/simplzpdf.serviceExample service configuration:
[Unit]
Description=Simplz.PDF FastAPI service
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/html/Simplz.PDF
Environment="PATH=/var/www/html/Simplz.PDF/.venv/bin"
ExecStart=/var/www/html/Simplz.PDF/.venv/bin/uvicorn wsgi:app --host 127.0.0.1 --port 5501 --workers 1
Restart=always
[Install]
WantedBy=multi-user.targetReload and enable the service:
sudo systemctl daemon-reload
sudo systemctl start simplzpdf.service
sudo systemctl status simplzpdf.service
sudo systemctl enable simplzpdf.serviceIf you expose the service behind Caddy:
yourdomain.com {
reverse_proxy 127.0.0.1:5501
}Or with Nginx:
server {
listen 80;
server_name simplzpdf.domain;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:5501;
}
}