- Python 100%
| examples | ||
| tests | ||
| LICENSE | ||
| pyproject.toml | ||
| qrgen.py | ||
| README.md | ||
| requirements.txt | ||
qrgen
Turn a link into print-ready QR code graphics.
qrgen https://example.org/mueller
This writes output/qr-mueller.svg (vector, ideal for print) and output/qr-mueller.png (roughly 1100 px). Pass several links to get several codes.
An optional batch mode reads a whole CSV and generates one code per row, each pointing to <base-url>/<slug>, plus a links.csv summary of all links. Works for anything that needs scannable links: posters and flyers, product or equipment labels, slides, event signage, or business cards whose short URLs redirect to vCards.
Runs on macOS and Linux with Python 3.9 or newer. Single file, pure Python, one dependency (segno).
Installation
pipx install git+https://code.nerdzoom.media/Marius/qrgen.git
# or
uv tool install git+https://code.nerdzoom.media/Marius/qrgen.git
Or run the script directly without installing:
pip install segno
python3 qrgen.py https://example.org/mueller
For --verify support, add the optional extras:
pipx install "qrgen[verify] @ git+https://code.nerdzoom.media/Marius/qrgen.git"
# or, when running the script directly:
pip install zxing-cpp pillow
Usage
Quick mode, one code per link:
qrgen https://example.org/mueller
qrgen https://example.org/a https://example.org/b --formats png
qrgen https://example.org/mueller --name max-mueller --out codes/
Batch mode from a CSV:
qrgen --csv people.csv --base-url https://example.org --dry-run
qrgen --csv people.csv --base-url https://example.org --verify
All options are listed by qrgen --help:
| Option | Default | Description |
|---|---|---|
URL ... |
one or more links to encode directly | |
--csv FILE |
batch mode: read people from a CSV | |
--base-url |
batch mode: URL prefix, the slug is appended | |
--name |
derived from URL | quick mode: filename stem for a single link |
--out |
output |
output directory (existing files are overwritten) |
--formats |
svg,png |
comma-separated subset of svg,png |
--error |
m |
QR error correction level: l, m, q, h |
--png-scale |
30 |
pixels per module (30 gives roughly 1100 px) |
--svg-scale |
10 |
SVG units per module |
--border |
4 |
quiet zone in modules (QR standard) |
--csv-delimiter |
; |
delimiter of the generated links.csv (batch mode) |
--dry-run |
print what would be generated, write nothing | |
--verify |
decode every code and compare it with its URL |
CSV format (batch mode)
Required column: name. Optional column: slug. All other columns are carried over into the summary links.csv. Comma, semicolon, and tab delimiters are detected automatically; UTF-8 with or without BOM works.
name;slug;role
Erika Mustermann;;Management
Max Mustermann;m-mustermann;Sales
Jürgen Größe;;IT
Ana de la Cruz;de-la-cruz;Design
Slug rules:
- Without an explicit slug, the last word of the name is used:
Erika Mustermannbecomesmustermann,Felix Kronlage-Dammersbecomeskronlage-dammers. Leading titles likeDr.are irrelevant since only the last word counts. - German umlauts are transliterated (
Größebecomesgroesse), other accents are stripped, everything is lowercased, and remaining characters are reduced toa-z,0-9, and-. - Explicit slugs are needed for multi-part surnames (
Ana de la Cruzwould otherwise becomecruz) and whenever two rows would resolve to the same slug. Colliding slugs abort the run with an error listing the affected rows, so nothing gets overwritten silently.
Output
output/
├── qr-<name>.svg vector, use this for print layouts
├── qr-<name>.png raster, roughly 1100 px at default scale
└── links.csv batch mode only: name, slug, URL, extra columns
In quick mode the filename comes from the last part of the link (.../mueller becomes qr-mueller.svg), or set it with --name. links.csv is written with a semicolon delimiter and a UTF-8 BOM so it opens cleanly in Excel and LibreOffice; change this with --csv-delimiter.
Print notes
- The quiet zone (4 modules of white space) is already part of every file, no extra margin needed.
- Recommended minimum print size: about 12 mm edge length.
- Error correction level
mis a good default for short URLs. Useqorhif the codes will be printed very small or on textured material.
Development
pip install -e ".[verify]" pytest
pytest
The Forgejo Actions workflow in .forgejo/workflows/ci.yml runs the test suite plus a smoke test on Python 3.9 and 3.13. It expects a Forgejo runner with a docker label; adjust runs-on if your runner uses different labels.
License
MIT, see LICENSE.