Skip to main content

Official Python SDK for Pictify - Generate images from HTML templates

Project description

Pictify Python SDK

Official Python SDK for Pictify — generate images, PDFs, and GIFs from raw HTML, live URLs, and reusable templates.

Installation

pip install pictify

Quick Start

from pictify import Pictify

client = Pictify(api_key="your-api-key")

# Render raw HTML to a PNG
image = client.render_html(html="<div style='font-size:48px;padding:40px'>Hello World</div>")
print(image.url)

# Render a reusable template
result = client.render("your-template-uid", variables={"name": "Ada", "company": "Pictify"})
print(result.url)  # results[0].url

Async Usage

import asyncio
from pictify import AsyncPictify

async def main():
    async with AsyncPictify(api_key="your-api-key") as client:
        image = await client.render_html(html="<div>Hello World</div>")
        print(image.url)

asyncio.run(main())

Features

  • Sync + async clientsPictify and AsyncPictify, identical surface
  • Full type hints — Pydantic result models with snake_case attributes
  • Automatic retries — exponential backoff on 5xx and network errors
  • Typed errorsAuthenticationError, RateLimitError, QuotaExceededError, and more
  • Templates, HTML, URLs & GIFs — one client for every render type
  • Async batch rendering — submit large jobs and poll for progress

Configuration

client = Pictify(
    api_key="your-api-key",
    base_url="https://api.pictify.io",  # optional: API base URL
    timeout=30.0,                       # optional: request timeout in seconds (default: 30)
    max_retries=3,                      # optional: retries on 5xx/network errors (default: 3)
)

Both clients are context managers and expose close():

with Pictify(api_key="your-api-key") as client:
    ...

async with AsyncPictify(api_key="your-api-key") as client:
    ...

API Reference

render_html(html, *, css=None, width=None, height=None, selector=None, format=None)

Render an image (or PDF) directly from HTML. POST /image.

image = client.render_html(
    html="<div style='padding:40px'>Hello</div>",
    css="div { color: blue; }",   # optional — inlined into a <style> tag
    width=1200,                    # optional (default: 1280)
    height=630,                    # optional (default: 720)
    selector="#card",             # optional — crop to a specific element
    format="png",                 # optional: 'png' | 'jpg' | 'jpeg' | 'webp' | 'pdf' (default: png)
)
print(image.url, image.id, image.created_at)

render_url(url, *, width=None, height=None, selector=None, format=None)

Screenshot a live URL. POST /image with url.

image = client.render_url(url="https://example.com", width=1280, height=720)
print(image.url)

render(template_id, *, variables=None, format=None, quality=None, width=None, height=None, layout=None, layouts=None)

Render a single image (or PDF) from a template. POST /templates/:uid/render.

The response is a results envelope; result.url is a convenience accessor for results[0].url.

result = client.render(
    "template-uid",
    variables={"title": "My Post", "author": "Ada"},
    format="png",   # optional: 'png' | 'jpg' | 'jpeg' | 'webp' | 'pdf' (default: png)
    quality=0.9,    # optional render quality, 0.1-1.0 (default: 0.9)
    width=1200,     # optional
    height=630,     # optional
)
print(result.url)
print(result.results[0])  # RenderResultItem: layout, url, width, height, format, name, id, created_at

render_layouts(template_id, layouts, *, variables=None, format=None, quality=None, width=None, height=None)

Render multiple layout variants of a template in one call (max 20). POST /templates/:uid/render with layouts.

Each successful layout appears in results; missing/invalid layouts appear in errors.

result = client.render_layouts(
    "template-uid",
    layouts=["default", "square", "story"],
    variables={"title": "Hello"},
)
for item in result.results:
    print(item.layout, item.url, f"{item.width}x{item.height}")
for err in result.errors:
    print("failed:", err.layout, err.error)

render_gif(*, html=None, url=None, template_id=None, variables=None, width=None, height=None, quality=None)

Render an animated GIF from raw HTML, a live URL, or a template. POST /gif.

Provide exactly one source: html, url, or template_id. The {gif: {...}} envelope is flattened.

gif = client.render_gif(
    html="<style>@keyframes p{...}</style><div class='anim'>Hi</div>",
    width=400,     # optional (default: 800)
    height=200,    # optional (default: 600)
    quality="medium",  # optional: 'low' | 'medium' | 'high' (default: medium)
)
print(gif.url, gif.uid, gif.animation_length)

render_batch(template_id, variable_sets, *, format=None, quality=None, concurrency=None, layout=None, layouts=None)

Submit an async batch render of a template across many variable sets (max 100). POST /templates/:uid/batch-render.

Returns immediately (HTTP 202) with a batch_id. Poll get_batch_results for progress. Rendered URLs are delivered via the render.completed webhook — they are not returned by the poll endpoint.

job = client.render_batch(
    "template-uid",
    variable_sets=[{"name": p["name"], "price": p["price"]} for p in products],
)
print(job.batch_id, job.status, job.total_items)

get_batch_results(batch_id)

Get the status, progress, and per-item results of a batch job. GET /templates/batch/:batchId/results.

status = client.get_batch_results(job.batch_id)
print(status.status, status.completed_items, "/", status.total_items)
for item in status.results:
    print(item.index, item.success, item.variables)  # no URLs (see webhook)

get_template(template_id)

Get a single template by its UID. GET /templates/:uid.

template = client.get_template("template-uid")
print(template.uid, template.name)
print([v.name for v in (template.variable_definitions or [])])

list_templates(*, page=None, limit=None, sort=None)

List templates in your account. GET /templates.

result = client.list_templates(page=1, limit=20, sort="newest")
for t in result.templates:
    print(t.uid, t.name)
print(result.pagination.total, result.pagination.has_next)

create_template(html, *, name=None, width=None, height=None, variable_definitions=None, output_format=None)

Create a template from HTML. Variables are auto-discovered from {{variableName}} tokens. POST /templates.

template = client.create_template(
    html="<div>Hi {{first_name}}</div>",
    name="Welcome Card",
    width=600,
    height=200,
)
print(template.uid)

Error Handling

from pictify import (
    Pictify,
    PictifyError,
    AuthenticationError,
    TemplateNotFoundError,
    RateLimitError,
    QuotaExceededError,
    RenderError,
    ServerError,
)

client = Pictify(api_key="your-api-key")

try:
    result = client.render("template-uid", variables={"title": "Hello World"})
except AuthenticationError:
    print("Invalid API key")
except TemplateNotFoundError:
    print("Template not found")
except RateLimitError as e:
    print(f"Rate limited. Retry after: {e.retry_after}s")
except QuotaExceededError:
    print("Render quota exceeded")
except RenderError as e:
    print(f"Render/validation failed: {e.message}; field errors: {e.errors}")
except ServerError as e:
    print(f"Server error: {e.message}")
except PictifyError as e:
    print(f"Error: {e.message}")

Status → error mapping: 401 → AuthenticationError, 402 → QuotaExceededError, 404 → TemplateNotFoundError, 422 → RenderError (with field-level errors), 429 → QuotaExceededError when code == "quota_exceeded" else RateLimitError, other 4xx → RenderError, 5xx → ServerError. Only 5xx and network errors are retried.

Type Hints

The SDK ships full type hints and Pydantic result models:

from pictify import (
    Pictify,
    AsyncPictify,
    ImageResult,
    RenderResult,
    RenderResultItem,
    GifRenderResult,
    BatchRenderResult,
    BatchResults,
    Template,
    ListTemplatesResult,
    ImageFormat,
    GifQuality,
)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pictify-1.0.0.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pictify-1.0.0-py3-none-any.whl (18.8 kB view details)

Uploaded Python 3

File details

Details for the file pictify-1.0.0.tar.gz.

File metadata

  • Download URL: pictify-1.0.0.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for pictify-1.0.0.tar.gz
Algorithm Hash digest
SHA256 a384acf564719f448d53782a96a4c8d94210b775d87113a0ec7273132603a923
MD5 9ad1198a057828c25f91b6667e566cf9
BLAKE2b-256 290463630701093588341666a5831f0ee062df230b6a4a90accc79d948860074

See more details on using hashes here.

File details

Details for the file pictify-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: pictify-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for pictify-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b5970ec3e9ed1eb23c0edb8267882bb4962e324b16cf3ccd8579385323b08ea6
MD5 c1920fb29e2127f705cdb4207eb2abf7
BLAKE2b-256 75e51de8f4af509af10355c78beb9ec4dd0e724e8425abb9a7e6fefd84601a57

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page