Python CLI that fills language slots in an existing Meta Ads Bulk Import .xlsx template. It opens the file with openpyxl, changes only localization cells, and writes a new workbook. The original column structure is never rebuilt.
The file example.xlsx has 103 columns on Sheet1. These headers exist and are used by name (not by column index):
| Slot | Language | Title | Body | Link | Display Link |
|---|---|---|---|---|---|
| 1 (default) | Default Language |
Title |
Body |
Link |
Display Link |
| 2–8 | Additional Language 1–7 |
Additional Title 1–7 |
Additional Body 1–7 |
Additional Link 1–7 |
Additional Display Link 1–7 |
Notes from the real file:
- There is no extra creative
Linkcolumn besides the existingLinkheader (columnAB) plusAdditional Link 1–7. Display Link/Additional Display Link 1–7also exist. If present, they are filled with the URL host and cleared for unused slots. The LLM still never invents URLs.Countriesis not changed. Region is written toSpecial Ad Category Country(D2), e.g.PE.
Need only curl and Python 3.10+. Git is not required.
curl -fsSL https://raw.githubusercontent.com/kirillswed/MetaConfigGen/main/install.sh -o install.sh && OPENROUTER_API_KEY=sk-or-... bash install.sh && cd MetaConfigGen && (source .venv/bin/activate || source .venv/Scripts/activate)The command downloads the installer, unpacks the repo zip, creates .venv, installs dependencies, writes .env, then activates the venv. If .venv/bin/activate is missing, Git Bash on Windows uses .venv/Scripts/activate.
If the key was skipped, put it in .env:
OPENROUTER_API_KEY=sk-or-...
OPENROUTER_MODEL=openrouter/free
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
The API key is never logged.
Interactive run — the script asks for languages (if missing) and region. A random physical object is generated for each language and taken from Wikipedia. Region is written to Special Ad Category Country (cell D2):
python main.py "example.xlsx" --languages языки здесьThen it asks:
Enter region:
Турция
Region names in any language are resolved by the model to an ISO country code and written to D2 (TR for Турция). Two-letter codes like PE are used as-is.
python main.py "example.xlsx" --languages языки здесь --geo PeruThe original file is copied to *_backup.xlsx. The result is written to localized_result.xlsx unless --output is set. The source file is not overwritten unless you pass --overwrite.
- 1 to 8 languages. More than 8 languages stops the run and does not write Excel.
- Unused slots 4–8 stay empty; columns are never deleted.
- All LLM localizations are validated before any cell is written.
- If the model returns a different URL, Python restores the Wikipedia URL for that language.
- After save, the result is reopened and checked: same row count, same column count, same header names/order, no edits outside the allowed localization columns.