Metadata-Version: 2.4
Name: ironfang-renderwolf
Version: 0.1.0
Summary: Renderwolf API client: screenshots, PDFs, QR codes, template images, clips and site previews from a URL or HTML.
Author: Ironfang Ltd
License-Expression: MIT
Project-URL: Homepage, https://ironfang.uk/renderwolf
Project-URL: Documentation, https://ironfang.uk/renderwolf/docs
Keywords: screenshot,pdf,qr,html-to-image,renderwolf,ironfang
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# ironfang-renderwolf

The official Python client for the [Renderwolf](https://ironfang.uk/renderwolf)
API: screenshots, PDFs, QR codes, template images, clips and site previews
from a URL or from HTML you send. No dependencies; Python 3.10 and later.

```sh
pip install ironfang-renderwolf
```

```python
import os
from ironfang_renderwolf import Renderwolf

with Renderwolf(api_key=os.environ["IRONFANG_API_KEY"]) as rw:
    shot = rw.screenshot(url="https://example.com", full_page=True)
    shot.save("page.png")
    print(shot.credits, shot.render_ms, shot.request_id)
```

Every render returns the bytes plus what the API reports about them: content
type, credits charged (zero on a cache hit), render time and the request id
to quote to support. Long outputs stream: `save()` and `iter_bytes()` never
hold a whole clip in memory.

## Durable jobs

```python
job = rw.submit_job("pdf", {"html": invoice_html, "paper_format": "a4"}, idempotency_key=f"invoice-{invoice.id}")
done = rw.wait_for_job(job["id"])
if done["status"] == "succeeded":
    rw.job_result(job["id"]).save(f"invoice-{invoice.id}.pdf")
```

## Verifying a webhook

Run the check over the raw request body, before parsing it.

```python
from ironfang_renderwolf import verify_webhook

ok = verify_webhook(
    secret=os.environ["RENDERWOLF_WEBHOOK_SECRET"],
    timestamp=request.headers["Renderwolf-Timestamp"],
    signature=request.headers["Renderwolf-Signature"],
    payload=request.get_data(),
)
```

## Errors

Failures raise `RenderwolfError` with `status`, the API's `code`
(`quota_exhausted`, `render_failed`, ...) and `request_id`. Synchronous
renders are never retried by the client: a render that timed out may already
have been charged, and retrying it blind doubles the bill.
