[KongchangAI]
· 2 min read· 1,320 words

One Python Script Generates Metadata CSVs for Adobe, Vecteezy, and Dreamstime

One Python Script Generates Metadata CSVs for Adobe, Vecteezy, and Dreamstime

A standard-library-only Python script generates metadata CSVs for Adobe, Vecteezy, and Dreamstime from one asset folder, with a ledger to prevent duplicate publishing.

After a CSV header error wasted an entire upload day, developer Revanzart wrote `make_metadata.py`, which relies only on the Python standard library to generate the metadata CSVs required by three platforms from a single asset folder. The headers are fixed and unforgiving: Adobe Stock 5 columns, Vecteezy 4, Dreamstime 15; a wrong header causes the whole batch to fail. The script defaults to converting filenames into titles but candidly notes the quality is weak and supports a `--titles` parameter for real titles and keywords. A companion `upload_tracker.py` ledger prevents duplicate publishing and account flags. The core idea is to automate structure, not judgment—using code to lock in platform rules and address the most tedious, error-prone step in bulk uploading.

Manually creating stock asset metadata CSVs is an invisible bottleneck in many creators' upload workflows. A single wrong column order can cause an entire batch upload to fail, and platforms usually give no clear warning. After a frustrating experience where a CSV header error wasted an entire upload day, developer Revanzart wrote make_metadata.py—a script that relies only on the Python standard library to generate the metadata CSV files required by three platforms from a single asset folder.

rss source: How make_metadata.py Builds Adobe, Vecteezy and Dreamstime CSVs From One Asset Folder

Three platforms, three non-negotiable header sets

According to the author's original description, each platform's CSV header is fixed and strict:

  • Adobe Stock: 5 fixed header columns. The uploader checks the header row first; if the column names or order do not match, the entire batch is rejected before evaluation.
  • Vecteezy: 4 fixed header columns. Fewer columns, but the same rules.
  • Dreamstime: 15 fixed header columns. This is the widest of the three and the easiest to get wrong when editing manually—each asset requires 15 cells, and one misplaced category code can get it sent back during review.

The script's design goal is very clear: scan a specified folder, filter by extension, write the exact headers required by the platform, and then write one row per file. No extra columns, no "helpful" additions. The author emphasizes that the script was written for headers that actually pass upload, and it writes nothing beyond that.

Background on metadata CSV formats for Adobe Stock, Vecteezy, and Dreamstime

The differences in metadata requirements among these three stock platforms stem from the historical design of their review processes and internal systems. Adobe Stock's submission system adopted strict CSV validation early on: the header row must exactly match the official template, with no deviation in column count, column names, or even capitalization, otherwise the entire file is rejected by the system before it reaches manual review. Vecteezy is smaller and has relatively streamlined field requirements, so only 4 columns are needed to map title, keywords, description, and category. Dreamstime, with its long history and complex categorization system, requires 15 columns covering title, description, keywords, category, model/property release status, and more, making manual entry highly prone to batch failure due to misaligned or missing columns. This "header as contract" design means bulk uploaders must match platform specifications precisely and cannot rely on generic templates.

Titles and keywords: defaults are usable, but the filename is not the title

By default, the script converts the filename to title case and uses it as the title. For example, running:

python make_metadata.py ./my-assets --platform adobe --out metadata.csv --ext .jpg

This generates a valid CSV that can be inspected and submitted. But the author candidly notes that titles like asset-001.jpg becoming "Asset 001" are weak, and reviewers will notice. Therefore the script supports the --titles titles.json parameter, allowing real titles and keyword sets to be provided for each asset.

The author's recommended workflow is: first generate the CSV with defaults, open it for inspection, then replace the lazy titles before submitting. The script is responsible for quickly producing a valid file; the quality of the final step remains under the creator's control. This candid positioning avoids overpromising.

One asset folder, three outputs, zero duplicate work

The core value of the single-folder design is that the same directory can feed all three platforms:

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

Same files, three CSVs, each with the correct headers. After packaging 39 products this way, the author's metadata step went from half a day of spreadsheet work per batch to three commands that run while the next batch renders.

The script uses only the Python standard library—no pip install, no dependencies that can break. When running this pipeline on a server with 1 vCPU and 2 GB of memory, this matters more than it sounds. A metadata builder that pulls in pandas and a scraping framework is overkill for writing CSV rows, and every dependency is memory that isn't available on a small machine.

Advantages of the Python standard library in lightweight pipelines

make_metadata.py uses only the Python standard library (such as csv, argparse, os, and json) and does not introduce third-party data analysis libraries like pandas. On resource-constrained servers (such as 1 vCPU and 2 GB of memory), this is crucial: pandas is convenient but brings tens of MB of memory overhead and potential version conflicts; the standard library's csv module is sufficient for reading and writing, header writing, and row generation, and requires no pip install, avoiding the risk of dependency breakage interrupting the pipeline. For metadata tasks that only need to generate fixed-format CSVs, the standard library approach is clearly superior to heavy frameworks in reliability and portability, especially for repeated runs in continuous integration or on low-cost cloud hosts.

An unforeseen failure mode: running it twice

After the CSV builder worked, the author created a new problem for himself: he ran a batch, got distracted, and ran it again. Duplicate publishing of assets is one of the fastest ways to get an account flagged, and the platform won't care whether it was an accident.

That is why the toolkit pairs make_metadata.py with upload_tracker.py—a small ledger, also using only the standard library:

python upload_tracker.py pending items.txt
python upload_tracker.py done "asset-001.jpg"
python upload_tracker.py status

Now, before submitting anything, pending shows what has not yet been published. Re-running does not cause duplicate publishing because the ledger remembers. In the author's words, it is a boring script, and boring is the point.

The risk of duplicate publishing and the need for an upload ledger

Stock platforms generally treat repeated submissions of the same asset as a violation, which may trigger account review, restrict upload privileges, or even result in a ban. Since platforms do not proactively warn that "this file has already been uploaded," a creator who gets distracted and re-runs a script during batch operations may unintentionally publish duplicates. upload_tracker.py maintains a simple local ledger (such as a text file recording submitted filenames) and uses the pending command to list unpublished items before each submission, thereby blocking duplicate operations at the process level. This ledger mechanism does not rely on platform APIs; it achieves idempotency checks using only file records, at extremely low cost but with effective protection against account risk.

Automate structure, not judgment

The author offers three battle-tested pieces of advice:

  1. Do not edit metadata CSVs by hand. The headers are fixed and unforgiving. Adobe is 5 columns, Vecteezy is 4, Dreamstime is 15. Write the headers once in code and never touch a spreadsheet again.
  2. Automate structure, not judgment. The script builds a valid file, but you still need to write titles and keywords that pass review. Plan for that last mile.
  3. Track every submission. A ledger takes 10 minutes to build but can prevent the one mistake that could cost you your account.

None of this is clever. It is the unglamorous layer between making art and getting art listed, and it is the layer that stalled the author the longest.

Tool positioning and use cases

make_metadata.py and upload_tracker.py are two of the four scripts in the Pipeline Starter Kit; the other two, md2pdf.py and pack_product.py, are responsible for converting Markdown to styled PDF and packaging products with a 1280x720 cover and 600x600 thumbnail, respectively. The entire kit is four standalone scripts, at most two third-party packages, and no cloud account required.

For creators who bulk-upload assets to platforms such as Adobe Stock, Vecteezy, and Dreamstime, scripts like these address the most tedious and error-prone part of the workflow. Their value is not in technical innovation but in process reliability—using code to lock in rules that platforms enforce but document poorly, and avoiding invisible failure modes in manual operations.

#Python script#metadata CSV#Adobe Stock#Vecteezy#Dreamstime#stock asset upload#Python standard library
Share:

Related articles