The Vectorising Step Most Sticker Sellers Skip
I watched a batch of 40 stickers die in a single afternoon.
Not the art. The art was fine. What died was the submission. I had exported every file as JPG, stacked them in a folder, and fired them at three platforms in one run. Adobe's uploader rejected the CSV on the first row. Vecteezy accepted the CSV and then refused half the files. Dreamstime sat there waiting for a 15 column sheet I did not have.
Then I ran the whole batch a second time, trying to fix it, and that is when I learned what a double post actually costs. The files were already in the queue. I had just uploaded them twice.
The vectorising step I skipped was never in the drawing app. It was in the pipeline. Here is what actually works.
The three CSVs are not the same CSV
This is the rule that eats the most hours. Each channel demands a different header, and a wrong header is rejected instantly, not warned about.
Adobe wants 5 columns. Vecteezy wants 4. Dreamstime wants 15. There is no shared format and no mercy on a typo.
I stopped hand building these after the second rejection. make_metadata.py writes the header the channel asked for and nothing else. One command per platform from the same folder of files:
python make_metadata.py ./my-assets --platform adobe --out metadata.csv --ext .jpg
python make_metadata.py ./my-assets --platform vecteezy --out vecteezy.csv --ext .jpg
python make_metadata.py ./my-assets --platform dreamstime --out dreamstime.csv --ext .jpg
Without a titles file it title cases the filename. That is a first pass, not a submission. Replace the titles before you upload. The script only enforces the shape of the sheet, you still own the words.
The important part is that it uses the standard library alone. No install, no dependency, nothing to break.
Double posting is the fastest way to get flagged
Running a batch twice is the single most expensive mistake in this workflow. It is not a small annoyance. It is the fastest route to an account review.
upload_tracker.py is a ledger. It remembers what you have already posted, so a re run can never double post:
python upload_tracker.py pending items.txt # shows what is NOT done yet
python upload_tracker.py done "asset-001.jpg"
python upload_tracker.py status
That is the whole tool. It does one job and it does it before you touch a browser.
Run one process at a time and measure the ceiling
The entire pipeline behind this ran on 1 vCPU, 2 GB RAM, no GPU, and packaged 39 finished products, 856 MB of output. It works because of habits, not hardware.
Never fan out image jobs in parallel on a 1 core box. Call gc.collect() after each asset to free memory between items. Measure peak RSS, not average: resource.getrusage(RUSAGE_SELF).ru_maxrss tells you the real ceiling, not the comfortable middle. For heavy render steps, process one file per subprocess so memory returns to the OS. And render at the resolution you need. Inspecting a preview at 60 dpi beats burning a 300 dpi render just to look at it.
None of this is clever. It is just the difference between a server that finishes the batch and one that dies on item 30.
A pack is a zip plus two images
A bare zip does not sell. A zip with a real cover does.
pack_product.py makes all three in one command:
python pack_product.py my-product "My Product" "A short subtitle" 9
That writes the zip, a 1280x720 cover, and a 600x600 thumbnail. Put them where you want with --dir or the PACK_ROOT environment variable, no editing the script.
The covers are the only reason Pillow is in the stack. md2pdf.py is the only reason reportlab is. That is two third party packages total. make_metadata.py and upload_tracker.py need nothing at all.
Keep the folder fixed and keep the research
A catalogue turns into a junk drawer without a fixed structure. This is the one the kit assumes:
project/
assets/ raw output (one file per asset)
output/ ready-to-submit files + metadata.csv
packs/ finished product zips + covers
research/ your notes and sources
scripts/ these tools
Keep research/ forever. That is the line this project crossed once and will not cross again. The scrape logs and notes are the raw material for the next product. Deleting them to clean up is how you delete your own pipeline.
There are 300+ pages of research behind the rules these scripts enforce, and roughly 19,000 lines of pipeline code in the parent project. The four scripts here are the packaging layer, and they were extracted from work that ran and shipped.
If you want the exact tools, the same ones that packaged the 39 products on a 1 core, 2 GB box, they are bundled with the playbook.
Building digital products? Free guides & kits for digital product sellers.
Top comments (0)