Why pack_product.py Renders Both a 1280×720 Cover and a 600×600 Thumbnail
I built 39 products on a 1 vCPU, 2 GB RAM server before I understood why my uploads kept getting rejected. The zip was fine. The files inside were fine. The problem was the packaging layer, and it took me 300+ pages of research across Adobe, Vecteezy, and Dreamstime to figure out that a single cover image was never going to survive every surface it landed on.
Here is what pack_product.py actually does, why it renders two images instead of one, and what that taught me about packaging digital products.
The failure that started it
My first batches looked clean on my laptop. Then the previews rendered. A 1280×720 JPG that read perfectly as a cover got crushed into a square market thumbnail and the text inside the safe area disappeared behind padding I never saw coming. Meanwhile a square thumbnail, when stretched to a banner slot, looked like a placeholder someone forgot to replace.
I was treating "a cover" as one job. It is two jobs with two different aspect ratios, and no amount of careful composition in a single file solves both at once. So pack_product.py renders both, every pack, with no flag to turn either off.
Why 1280×720 for the cover
The cover is the hero image. It is what the buyer sees first on a product page or a marketplace listing, and it is the one they judge in roughly two seconds. 1280×720 gives you a wide 16:9 canvas where a title, a subtitle, and a hint of the contents can all breathe without fighting for room. That is the surface where a product looks like a product, not a file dump.
The cover is also where most of your text lives, and text is the fragile part. A wide canvas keeps the text comfortably inside the frame, so a title that reads fine at full size does not get clipped when the page compresses the image into a card.
Why 600×600 for the thumbnail
The thumbnail is the survival test. It shows up in grids, search results, category rows, and recommendation strips, often at 100px or less, often cropped to a square. If your cover is your only image, the square crop eats your text or your centered art.
600×600 forces you to design for the grid. You get a square canvas, you place the one element that must read at small size in the middle, and you accept that everything else is decoration. When someone scrolls a wall of thumbnails, your square needs to be legible in a glance. That is a different design problem from the hero cover.
The same bundle, two files, one pass
pack_product.py takes the product name, a subtitle, and a count, zips the files, and writes three files in one run: my-product.zip, my-product-cover.jpg, and my-product-thumb.jpg, into a _system folder next to where you run it. Point it elsewhere with --dir or the PACK_ROOT environment variable. No editing the script, no second pass.
python pack_product.py my-product "My Product" "A short subtitle" 9
That command is the whole packaging step. Pillow renders both images. Nothing else is needed, because this is the only script in the kit that touches a third-party image library. The other heavy lifting in the pipeline runs on the standard library.
The rule I now follow
A zip with a real cover sells; a bare file does not. That one line is why pack_product.py exists and why it refuses to render just one image. The cover earns the click, the thumbnail survives the grid, and they are never the same picture.
If you take one thing from this, make it the two-canvas habit. Build the wide hero and the square grid image as separate deliverables in the same pass, and stop trying to make one file do work it was never designed for.
Where this came from
pack_product.py is one of four standalone scripts in the Pipeline Starter Kit: make_metadata.py builds the exact Adobe 5-column, Vecteezy 4-column, and Dreamstime 15-column CSVs; upload_tracker.py is the ledger that stops re-runs from double-posting; md2pdf.py turns Markdown into a clean PDF for selling docs. The whole kit ran on one process at a time, freed memory between assets with gc.collect(), and measured real peak RSS rather than guessing, all on a single-core 2 GB box with no GPU. Those habits are not optional when the server is that small. They are the reason the pipeline ever finished.
That kit is the packaging layer of the full system: 39 finished products, 856 MB of output, and the research notes behind every header rule. The product is called digital asset factory, and the kit in it is the set of tools that actually packaged the catalogue.
Building digital products? Free guides & kits for digital product sellers.
Top comments (0)