ironfang-render
The official Python client for the Ironfang Render 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.
Formerly ironfang-renderwolf; 2.0.0 removed ironfang_renderwolf and the old
Renderwolf and RenderwolfError names. Webhooks are signed with the
Ironfang-* headers.
3.0.0 follows Ironfang's move from credits to metered usage on one billing
account: a render reports meter and quantity instead of credits, a job
reports usage instead of credits, usage() returns the month per meter,
request history records meter and quantity, and billing refusals raise
IronfangBillingError. Renders accept idempotency_key.
pip install ironfang-render
import os
from ironfang_render import IronfangRender
with IronfangRender(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.meter, shot.quantity, shot.render_ms, shot.request_id)
Every render returns the bytes plus what the API reports about them: content
type, the billing meter it counted against and the quantity it counted there
(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.
Change the page before capture
rw.screenshot(
html="<div class='chat-widget'>Chat</div><details id='details'><summary id='show-more'>Pricing</summary><p>Expanded pricing</p></details>",
css=".chat-widget { display: none !important; }",
script="document.querySelector('#show-more').textContent = 'Show pricing';",
actions=[
{"type": "click", "selector": "#show-more"},
{"type": "wait_for_selector", "selector": "#details[open]"},
],
).save("expanded.png")
The same options work with rw.pdf() and URL input. After normal load/waits,
Ironfang Render applies CSS, awaits the script, then executes actions in order
before settling and capture. JavaScript runs in the target page context as an
async function body; use await or return a promise for asynchronous work. It
has a five-second limit (or the remaining render timeout, if shorter).
CSS is limited to 64 KiB of UTF-8, script to 16 KiB, and actions to 20. Actions
are click, hover, wait_for_selector (presence), and delay with
duration_ms; combined delays may total at most 10,000 ms. Selectors are limited
to 1,024 UTF-8 bytes and share the render timeout. Invalid input returns
bad_request; script/action execution errors return sanitized render_failed
messages. A screenshot cache hit does not re-execute controls; use no_cache
for fresh execution. Full reference.
Durable jobs
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")
The job's usage says what it holds: {"meter", "reserved", "committed"}.
The most the job can count is reserved when it is accepted, and what it
produced is committed when it succeeds. A job that fails or is cancelled while
queued counts nothing.
Usage and billing
Ironfang Render has no plans or credits. Usage is billed to your organisation's Ironfang billing account, shared by every Ironfang product and managed in Billing in the Ironfang portal. Each kind of render counts against a meter, and each meter has a monthly free allowance; beyond it, usage is pay-as-you-go once paid usage is enabled.
usage = rw.usage()
for m in usage.get("meters", []):
print(m["id"], m["used"], m["remaining_free"])
Verifying a webhook
Run the check over the raw request body, before parsing it.
from ironfang_render import verify_webhook
ok = verify_webhook(
secret=os.environ["RENDER_WEBHOOK_SECRET"],
timestamp=request.headers["Ironfang-Timestamp"],
signature=request.headers["Ironfang-Signature"],
payload=request.get_data(),
)
Errors
Failures raise IronfangRenderError with status, the API's code
(render_failed, rate_limited, ...), request_id and, when the API sent
one, retry_after in seconds. Branch on code rather than the status: rate
limits and billing refusals can share a 429.
When the billing account refuses a render, nothing is rendered or counted and
the error is an IronfangBillingError (a subclass) with product, and
meter and reset_at when the API states them. The codes are
free_allowance_exhausted, account_budget_exhausted,
product_budget_exhausted, exemption_limit_reached, paid_usage_paused,
payment_required, payment_action_required, account_restricted,
product_not_eligible, account_closed, operation_too_large and
billing_temporarily_unavailable. Only the last clears by itself, after
retry_after; the rest are resolved in Billing or when the month rolls over.
from ironfang_render import IronfangBillingError
try:
rw.screenshot(url="https://example.com")
except IronfangBillingError as err:
print(err.code, err.reset_at)
Synchronous renders are never retried by the client: a render that timed out
may already have counted, and retrying it blind counts it twice. Pass
idempotency_key to make a render count at most once; the same key again is
refused with idempotency_key_used, since a synchronous result is not kept.
Metadata
Release files for ironfang-render 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ironfang_render-3.0.0.tar.gz | 16.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ironfang_render-3.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.2 kB
Release files / ironfang_render-3.0.0.tar.gz
| Download URL | ironfang_render-3.0.0.tar.gz |
|---|---|
| Size | 16.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c8443c75ba2aa7527f015c97af3f6ec74b68d712cd0215909cab39847676324f
|
|
BLAKE2b-256 checksum How to use checksums |
ddcf036d0a8a0cb1f12d3ed4ad95114d5cb0874ad5076e4479bb94408f6feb4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / ironfang_render-3.0.0-py3-none-any.whl
| Download URL | ironfang_render-3.0.0-py3-none-any.whl |
|---|---|
| Size | 11.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5a8e12cbe9294976331bade6ee3d28f0776e2c7c22fe2319257ac646c5113023
|
|
BLAKE2b-256 checksum How to use checksums |
87dcc00b3f821f358ddb1683583886553b029efebe063c331a873d1e8e9dd607
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Security for ironfang-render 3.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.