# How to generate a PDF from HTML in Python

# How to Generate a PDF from HTML in Python

The usual Python options for HTML-to-PDF: `wkhtmltopdf` (requires a system binary), `WeasyPrint` (CSS support gaps, heavy dependencies), or Puppeteer via subprocess (a browser in your Python app). All of them require you to manage something at the OS level.

An API call requires nothing:

```python
import requests

response = requests.post(
    'https://pagebolt.dev/api/v1/pdf',
    headers={'x-api-key': 'YOUR_API_KEY'},
    json={
        'html': '<h1>Hello</h1><p>This is my PDF.</p>',
        'format': 'A4',
        'printBackground': True
    }
)

with open('output.pdf', 'wb') as f:
    f.write(response.content)
```

## Generate from a URL

If the page is already live, pass a URL instead of HTML:

```python
response = requests.post(
    'https://pagebolt.dev/api/v1/pdf',
    headers={'x-api-key': 'YOUR_API_KEY'},
    json={
        'url': 'https://example.com/report',
        'format': 'A4',
        'printBackground': True,
        'blockBanners': True
    }
)
```

## Invoice generation with Jinja2

A common pattern: render an HTML template, then convert to PDF on the fly:

```python
import requests
from jinja2 import Template

template = Template("""
<html>
<body style="font-family: sans-serif; padding: 40px;">
  <h1>Invoice #{{ invoice_id }}</h1>
  <p>Customer: {{ customer }}</p>
  <p>Amount due: ${{ amount }}</p>
  <p>Due date: {{ due_date }}</p>
</body>
</html>
""")

html = template.render(
    invoice_id=1042,
    customer="Acme Corp",
    amount="299.00",
    due_date="2026-03-01"
)

response = requests.post(
    'https://pagebolt.dev/api/v1/pdf',
    headers={'x-api-key': 'YOUR_API_KEY'},
    json={'html': html, 'format': 'A4', 'printBackground': True}
)

with open(f'invoice-1042.pdf', 'wb') as f:
    f.write(response.content)
```

## In a Django/Flask view

```python
from django.http import HttpResponse
import requests

def invoice_pdf(request, invoice_id):
    html = render_invoice_html(invoice_id)

    resp = requests.post(
        'https://pagebolt.dev/api/v1/pdf',
        headers={'x-api-key': settings.PAGEBOLT_API_KEY},
        json={'html': html, 'format': 'A4', 'printBackground': True}
    )

    return HttpResponse(
        resp.content,
        content_type='application/pdf',
        headers={'Content-Disposition': f'attachment; filename="invoice-{invoice_id}.pdf"'}
    )
```

## Options

```python
{
    'html': '...',          # raw HTML string
    'url': '...',           # OR a live URL
    'format': 'A4',         # A4, Letter, Legal, A3
    'printBackground': True,
    'margin': {
        'top': '20mm', 'bottom': '20mm',
        'left': '15mm', 'right': '15mm'
    },
    'landscape': False,
    'blockBanners': True
}
```

No system dependencies, no binary installs, no version pinning. Runs anywhere Python runs — Lambda, Cloud Run, a VPS, or your local machine.

---

Try it free — 100 requests/month, no credit card. → [pagebolt.dev](https://pagebolt.dev)
