Upload a picture and get it back redrawn as a wobbly MS Paint doodle.
This example demonstrates how to leverage multiple Cloudflare services to create a full-featured image processing pipeline using Python Workers.
- Python Workers — the runtime
- FastAPI — the HTTP API, served over ASGI
- R2 — stores uploaded originals and redrawn outputs
- Queues — hands work off the request path
- Workflows — durable, retrying background execution
- Workers AI — image generation guided by the uploaded reference
- Pillow — image normalization inside the Workflow
- Static Assets — the plain HTML/CSS/JS frontend
flowchart LR
Browser["Browser"]
Worker["Python Worker<br/>FastAPI"]
Queue[["Queue"]]
Workflow["Workflow"]
R2[("R2")]
AI["Workers AI"]
Browser --> Worker
Worker --> R2
Worker --> Queue
Queue --> Workflow
Workflow --> R2
Workflow --> AI
- The browser POSTs the image bytes to the Worker.
- FastAPI validates the image and stores the original in R2, and enqueues the job.
- The queue consumer turns each batch of IDs into Workflow instances.
- The Workflow reads the original from R2, normalizes it with Pillow, calls Workers AI, and stores the result back in R2.
First ensure that uv is installed:
https://docs.astral.sh/uv/getting-started/installation/#standalone-installer
Workers AI is a remote binding, even during local development. wrangler.jsonc
declares "ai": { "binding": "AI", "remote": true }, so inference always runs on
Cloudflare's network and bills against your account. Log in before starting the
dev server:
uv run pwrangler loginuv run pywrangler devThen open http://localhost:8787/ in your browser.
uv run pywrangler deploy