Generate report PDFs in Python

The simplest way to generate report PDFs in Python is to POST a report template and a JSON data object to the Docweave API — no headless browser to install, launch, or keep alive in your Python process.

Report template example

Any HTML works as a template. Use {{ placeholders }} for the title, period, summary metrics, and a data table:

<article style="font-family: sans-serif; color: #111;">
  <header>
    <h1>{{ title }}</h1>
    <p>Reporting period: {{ period }}</p>
  </header>

  <section>
    <h2>Summary</h2>
    <ul>
      <li>Total revenue: {{ total_revenue }}</li>
      <li>New customers: {{ new_customers }}</li>
      <li>Churn rate: {{ churn_rate }}</li>
    </ul>
  </section>

  <section>
    <h2>Detail</h2>
    <table style="width:100%; border-collapse:collapse;">
      <thead>
        <tr>
          <th style="text-align:left; border-bottom:1px solid #ccc;">Metric</th>
          <th style="text-align:right; border-bottom:1px solid #ccc;">Value</th>
        </tr>
      </thead>
      <tbody>
        {{{ rows }}}
      </tbody>
    </table>
  </section>
</article>

Generate the PDF in Python

Using requests, POST the template and your report data to /api/v1/pdf, then write the raw response bytes to a file:

import requests

template = """<article style="font-family: sans-serif; color: #111;">
  <header>
    <h1>{{ title }}</h1>
    <p>Reporting period: {{ period }}</p>
  </header>

  <section>
    <h2>Summary</h2>
    <ul>
      <li>Total revenue: {{ total_revenue }}</li>
      <li>New customers: {{ new_customers }}</li>
      <li>Churn rate: {{ churn_rate }}</li>
    </ul>
  </section>

  <section>
    <h2>Detail</h2>
    <table style="width:100%; border-collapse:collapse;">
      <thead>
        <tr>
          <th style="text-align:left; border-bottom:1px solid #ccc;">Metric</th>
          <th style="text-align:right; border-bottom:1px solid #ccc;">Value</th>
        </tr>
      </thead>
      <tbody>
        {{{ rows }}}
      </tbody>
    </table>
  </section>
</article>"""

data = {
    "title": "Q2 Sales Report",
    "period": "Apr 1 – Jun 30, 2026",
    "total_revenue": "$482,110",
    "new_customers": "126",
    "churn_rate": "2.3%",
    "rows": "".join(
        f"<tr><td>{name}</td><td style='text-align:right'>{value}</td></tr>"
        for name, value in [
            ("Monthly active users", "18,204"),
            ("Average order value", "$96.40"),
            ("Support tickets", "312"),
        ]
    ),
}

response = requests.post(
    "https://docweave.dev/api/v1/pdf",
    headers={
        "Authorization": "Bearer dw_live_your_key",
        "Content-Type": "application/json",
        "Accept": "application/pdf",
    },
    json={
        "source": {
            "type": "template",
            "template": template,
            "data": data,
        },
        "idempotencyKey": "q2-2026-sales-report",
    },
)

response.raise_for_status()

with open("report.pdf", "wb") as f:
    f.write(response.content)

…or from an AI agent

An AI agent doesn't need Python or an HTTP client at all. Run npx @docweave/mcp and the agent gets a generate_pdf tool that wraps the same orchestration:

// An AI agent can generate the same report over MCP, no HTTP client needed:
// npx @docweave/mcp
generate_pdf({
  source: {
    type: "template",
    template: "<h1>{{ title }}</h1><p>{{ period }}</p>...",
    data: { title: "Q2 Sales Report", period: "Apr 1 – Jun 30, 2026" }
  },
  outputPath: "/tmp/report.pdf"
})

FAQ

What's the simplest way to generate a report PDF in Python?

POST a report template and a JSON data object to Docweave's /api/v1/pdf endpoint using the requests library, then write the raw response bytes to a file. There's no headless browser to install, configure, or keep patched in your Python environment.

Can I generate a report PDF from an existing HTML report or a URL instead of a template?

Yes. Docweave's source can be an HTML string, a URL, or a template + JSON — pick whichever fits your report. Templates are usually the best fit for recurring reports because the layout stays fixed and only the data changes per run.

How do I avoid generating the same report PDF twice if my Python script retries?

Pass an idempotencyKey (for example the report period or a run ID). A retried request with the same key returns the previously generated PDF instead of rendering — and billing — again.

How is report PDF generation priced?

Pricing is per document, not per page. A short one-page summary and a long multi-page report with data tables cost the same, so adding detail to a report never increases the price.

Ready to generate report PDFs in production?

Get an API key

Related