I had 39 finished products sitting in a folder and nothing to sell. Every zip was just files. No cover image, no thumbnail, no way to show anyone what was inside. I uploaded one to Gumroad as a bare zip and it looked exactly like what it was: a random archive nobody would trust with a dollar.
The fix took one evening and one script. The lesson took longer: a zip isn't shippable until it has a cover. Here is what I learned getting from 39 bare zips to 1,700 assets made, 58 live on Adobe Stock, and a first sale of $0.99.
The cover is the product page
A 1280×720 cover and a 600×600 thumbnail are not decoration. They are the only thing a buyer sees before deciding whether to open their wallet. Marketplace thumbnails are small, and a zip file icon communicates nothing. When I added a rendered cover with the product title and subtitle baked in, the product started looking like something a person made on purpose.
The script that does this, pack_product.py, uses Pillow and nothing else. It takes a folder, a title, a subtitle, and a price, and writes three files: the zip, the cover, and the thumbnail. One command:
python pack_product.py my-product "My Product" "A short subtitle" 9
It writes into a _system folder by default, configurable with --dir or the PACK_ROOT environment variable. No editing the script, no framework, no cloud account.
Packaging is where solo makers stall, not creation
Making the art is the fun part. The four things that actually stall people are metadata, double-posting, turning a doc into a product, and packaging. I hit all four.
Metadata first. All three stock channels reject a wrong CSV header instantly. Adobe wants a 5-column header, Vecteezy wants 4 columns, Dreamstime wants 15. Guess one column and your whole batch bounces. My metadata script writes the exact header each platform demands and nothing else, built straight from a folder of files:
python make_metadata.py ./my-assets --platform adobe --out metadata.csv --ext .jpg
Without a titles file it title-cases the filename as a placeholder. Fine for a first pass, but replace it before you submit. Reviewers notice lazy titles.
Double-posting is the fastest way to get flagged
This one cost me real anxiety. Run your upload batch twice, because you lost track of what you already submitted, and you are posting duplicates. That is the kind of behavior that gets an account flagged. With 58 assets live on Adobe, I was not willing to risk that over bad bookkeeping.
So the pipeline has a ledger. upload_tracker.py is a plain-text tracker that remembers what is done:
python upload_tracker.py pending items.txt
python upload_tracker.py done "asset-001.jpg"
python upload_tracker.py status
A re-run never double-posts. It uses the standard library alone, no pip install at all. Two of the four scripts in my kit need nothing but Python 3.9+.
The whole thing runs on a 1-core, 2 GB box
I did not have a GPU farm. The pipeline ran on 1 vCPU and 2 GB RAM, no GPU, and it packaged 856 MB of output across those 39 products. It works because of habits, not hardware:
- One process at a time. Never fan out image jobs in parallel on a single core.
- Call
gc.collect()after each asset to free memory between items. - Measure peak RSS, not average, with
resource.getrusage(RUSAGE_SELF).ru_maxrss. Average lies, the peak is your real ceiling. - One file per subprocess for heavy render steps, so memory actually returns to the OS.
- Render at the resolution you need. Inspecting a preview at 60 dpi beats rendering at 300.
The same logic applies to AI image generation costs. Every wasted render is money. Inspect cheap, render once, package once.
Keep your research folder forever
One structural mistake I made exactly once: deleting my research folder to "clean up". Scrape logs, notes, keyword lists. Those are the raw material for the next product. Now the layout is fixed and the research folder is permanent:
project/
assets/ raw output
output/ ready-to-submit files + metadata.csv
packs/ finished zips + covers
research/ notes and sources, never deleted
scripts/ the tools
A catalogue without a fixed structure turns into a junk drawer. This layout is what the scripts assume, and it scales from 1 product to 39 without rethinking anything.
What it added up to
1,700 assets made. 58 live on Adobe Stock. First sale: $0.99. That number is small and I am not going to pretend otherwise. But it is real money from a pipeline that runs on a server weaker than most laptops, and the bottleneck was never the art. It was packaging and metadata, the boring layer nobody writes tutorials about.
The four scripts in this post are the packaging layer of a bigger system. The full thing, the prompt engine, the orchestrator, the research layer, is what I call the digital asset factory, and I wrote it all down as an honest playbook with the same tools included. No hype, just the system that produced those numbers.
Building digital products? Free guides & kits for digital product sellers.
Top comments (0)