RendShot

Windmill Integration — Image Generation in Scripts & Flows

Generate images from HTML in Windmill scripts using the RendShot Python SDK or TypeScript fetch. No extra setup needed.

Windmill is an open-source platform for building scripts, workflows, and internal tools. Since Windmill scripts are standard Python or TypeScript, you can use the RendShot SDK or plain HTTP calls directly — no community node or plugin required.

Prerequisites

  • A RendShot API key (get one free)
  • A Windmill workspace (cloud or self-hosted)

Option 1: Python Script with SDK

Windmill auto-installs Python packages from your imports. Just import rendshot and it works.

Create the script

Click + Script → choose Python → paste:

import rendshot

def main(title: str, author: str = "RendShot"):
    """Generate a blog cover image from dynamic data."""

    client = rendshot.RendShot(
        api_key=wmill.get_variable("f/rendshot/api_key")
    )

    image = client.render_image(rendshot.RenderImageOptions(
        template_id="blog-cover",
        variables={"title": title, "author": author},
        width=1200,
        height=630,
    ))

    return {"url": image.url, "id": image.id}

Windmill parses the import rendshot line and auto-installs the rendshot PyPI package when you save.

Store your API key

Go to ResourcesVariablesAdd variable:

  • Path: f/rendshot/api_key
  • Value: rs_live_YOUR_KEY
  • Mark as Secret

Access it in scripts with wmill.get_variable("f/rendshot/api_key").

Option 2: TypeScript Script with fetch

Windmill runs TypeScript via Bun. Use the built-in fetch API:

export async function main(title: string, author: string = "RendShot") {
  const apiKey = await Deno.env.get("RENDSHOT_API_KEY")
    ?? await wmill.getVariable("f/rendshot/api_key");

  const res = await fetch("https://api.rendshot.ai/v1/image", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      template_id: "blog-cover",
      variables: { title, author },
      width: 1200,
      height: 630,
    }),
  });

  const data = await res.json();
  return { url: data.url, id: data.id };
}

You can also import { RendShot } from '@rendshot/sdk' — Windmill auto-installs npm packages from imports.

Using in Flows

Wire the script into a Windmill Flow:

  1. Trigger — Cron schedule, webhook, or another script's output
  2. RendShot script — Takes dynamic data as input, returns { url, id }
  3. Next step — Send the image URL to Slack, email, update a database, etc.

Example: Weekly report image → Slack

Cron (every Monday 9am)
  → Query database for weekly stats
  → RendShot script (template: "weekly-report", variables: stats)
  → Slack "Send Message" (include image URL)

URL Screenshots

For capturing live URLs instead of rendering HTML, use the screenshot endpoint:

image = client.screenshot(rendshot.ScreenshotOptions(
    url="https://example.com",
    width=1280,
    height=720,
))

Troubleshooting

IssueFix
ModuleNotFoundError: rendshotSave the script first — Windmill installs dependencies on save
401 UnauthorizedCheck the variable path in wmill.get_variable() matches exactly
Slow first runFirst execution installs dependencies; subsequent runs use cache

Next steps

On this page