DEV Community

Cover image for Four Scripts, 39 Products: How I Turned One Prompt Engine Into an Assembly Line**

Four Scripts, 39 Products: How I Turned One Prompt Engine Into an Assembly Line**

I still have the CSV that Adobe rejected at 2:14 on a Tuesday morning. Twelve rows, twelve assets, all bounced in under a minute. The reason was stupid: my header had four columns because I'd built it from a Vecteezy template. Adobe wants five. Not five-ish, five, in their order, and their uploader rejects the whole file without telling you which row is wrong. I fixed the header by hand, resubmitted, and lost an hour I'll never get back.

That night is why there are four scripts on my server now. Together they've packaged 39 products, 856 MB of finished output, and they run on a 1 vCPU, 2 GB RAM box with no GPU. Here's what each one taught me.

The metadata problem is a formatting problem, so stop solving it by hand

Every stock platform has its own CSV shape. Adobe is 5 columns. Vecteezy is 4. Dreamstime is 15. All three reject a wrong header instantly, before they even look at your files. The fix is boring: one script that knows the three headers and writes them exactly. make_metadata.py takes a folder of files and emits the right CSV per platform:

python make_metadata.py ./my-assets --platform adobe --out metadata.csv --ext .jpg
Enter fullscreen mode Exit fullscreen mode

It uses only the standard library. Nothing to install. If you pass a titles JSON it uses your real titles and keywords. If you don't, it title-cases the filename, which is fine for a first pass and bad for a final one. Replace the filename titles before you submit. Reviewers notice.

Double-posting is the fastest way to get flagged, and batching makes it inevitable

The failure mode nobody warns you about: you run a batch of 40 uploads, the connection drops at row 31, you fix it, you rerun the whole thing, and now 30 assets exist twice. That pattern is exactly what account reviews look for. My answer is upload_tracker.py, a plain ledger:

python upload_tracker.py pending items.txt
python upload_tracker.py done "asset-001.jpg"
python upload_tracker.py status
Enter fullscreen mode Exit fullscreen mode

A re-run only ever touches what's marked pending. It's not clever. That's the point. It has prevented the rerun mistake on every batch since, and it also uses nothing but the standard library.

A product is a zip, a cover, and a thumbnail, not a folder

The difference between something that sells and something that sits there is packaging. I learned this from my own numbers: 1,700 assets made, 58 live on Adobe, and my first sale was $0.99. That sale did not come from a loose file. It came from a bundled product with a real cover. pack_product.py writes the zip, a 1280×720 cover, and a 600×600 thumbnail in one command:

python pack_product.py my-product "My Product" "A short subtitle" 9
Enter fullscreen mode Exit fullscreen mode

Cover rendering is the only place Pillow gets involved. For turning written content into a sellable product, md2pdf.py takes Markdown to a styled PDF, headings, tables, lists, links, via reportlab. Those are the only two third-party packages in the whole kit.

The 2 GB server rules

Everything above runs on a machine with 1 vCPU and 2 GB RAM, no GPU. That only works because of habits I learned by crashing the box a few times:

  • One process at a time. Never fan out image jobs in parallel on a single core.
  • Call gc.collect() after each asset. Free the memory before you start the next one.
  • Measure peak RSS with resource.getrusage(RUSAGE_SELF).ru_maxrss, not average usage. Peak is what kills you.
  • Run heavy render steps one file per subprocess so memory goes back to the OS.
  • Render at the resolution you need. Inspecting a preview at 60 dpi instead of 300 is the difference between fitting and swapping.

The other habit is organizational. The kit assumes a fixed folder layout: assets/ for raw output, output/ for ready-to-submit files, packs/ for finished products, research/ for notes. Keep research/ forever. I once deleted my scrape logs to clean up and regretted it, they're the raw material for the next product.

What this actually added up to

The honest ledger: 1,700 assets generated, 58 accepted and live on Adobe, 39 products packaged, first sale $0.99. That's not a quit-your-job number. It's proof the assembly line works end to end, on hardware that costs almost nothing, with a pipeline of about 19,000 lines built on 300+ pages of research into what each platform's review process actually enforces.

The four scripts are the packaging layer of that pipeline. I've pulled them out into a standalone kit with the install steps, the quick-start commands above, and the folder structure they assume. Two dependencies, no framework, no cloud account, validated on the same 1 vCPU / 2 GB box they ran on originally. If you want the tools rather than the story, that's the kit.

Get digital asset factory


Building digital products? Free guides & kits for digital product sellers.

Top comments (0)