Skip to main content

qrcody

Standalone Python port of qrcody's styled QR code SVG rendering engine — square/rounded/dots/blob/bars/squircle pixel styles, styled finder eyes and pupils, gradients, and framed export (perimeter / scan-me / scan bands). No browser, no server — pure functions in, SVG string out.

This is a hand-port of src/lib/buildSVG.js from the qrcody web app. The rendering logic itself has no DOM dependency in the original (it already runs inside a Cloudflare Worker), so the two implementations produce visually equivalent output, though exact numeric string formatting may differ slightly (e.g. 500 vs 500.0) — SVG renderers treat these identically.

Install

uv add qrcody
# or, for PNG export too:
uv add "qrcody[png]"

PNG export uses cairosvg, which needs the native Cairo library installed on the system (brew install cairo on macOS, apt install libcairo2 on Debian/Ubuntu).

Library usage

from qrcody import DEFAULT, build_svg, build_framed_svg

settings = {
    **DEFAULT,
    "text": "https://example.com",
    "pixels_style": "dots",
    "eyes_style": "circle",
    "frame": "scan-me",
    "frame_text": "Scan me",
}

qr_svg = build_svg(settings)
framed = build_framed_svg(qr_svg, settings)
svg_string = framed["svg"]  # framed["w"] / framed["h"] give the output dimensions

Layout check

validate_qr_layout(settings) inspects the same settings for problems that hurt scannability — an inadequate quiet zone, text that overflows the error-correction level, a center logo over a finder pattern or beyond error-correction capacity, frame text crowding the QR body — before you render:

from qrcody import validate_qr_layout

result = validate_qr_layout(settings)
if result["severity"] == "error":
    raise ValueError("; ".join(i["message"] for i in result["issues"]))

result["severity"] is "ok", "warn", or "error"; each issue is a dict with code, severity, and a human-readable message.

For PNG (requires the png extra):

from qrcody.png import svg_to_png

png_bytes = svg_to_png(svg_string, width=1000)

CLI

qrcody --url "https://example.com" --pixels squircle --frame perimeter -o qr.svg
qrcody --url "https://example.com" --pixels dots --eyes circle -o qr.png

Run qrcody --help for the full flag list — it mirrors the qrcody /api/qr HTTP API parameters (see the qrcody repo's functions/api/qr.js and public/openapi.yaml).

Settings dict

All keys from qrcody.DEFAULT (see defaults.py) are recognized; unspecified keys fall back to their default. Notable ones:

Key Values
pixels_style square / rounded / dots / blob / bars-h / bars-v / squircle
eyes_style square / rounded / circle / leaf / squircle
pupils_style square / rounded / circle / squircle
corners_style none / round / extra-round / squircle
frame none / perimeter / scan-me / scan
correction_level L / M / Q / H

Development

uv sync --extra png
uv run pytest
uv run ruff check .

Known gaps vs. the JS implementation

  • Logo embedding (logo / logo_scale settings) is supported in build_svg the same way as the JS version — pass a data URI as logo. There is no server-side "fetch a logo URL" helper here (that lives in the qrcody Cloudflare Worker's SSRF-hardened fetch, which is deployment-specific and out of scope for this package).
  • No automated JS/Python golden-file parity test yet — the port was done by hand against src/lib/buildSVG.js and verified with a matching unit test suite, but the two aren't diffed against each other in CI. If the JS renderer changes, this package needs a manual re-sync.

Note on the package name

This package is published as qrcody on PyPI, distinct from the qrcody npm/web app it's ported from — there's no npm/PyPI namespace collision since they're different registries.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qrcody-1.14.0.tar.gz (13.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qrcody-1.14.0-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

Details for the file qrcody-1.14.0.tar.gz.

File metadata

  • Download URL: qrcody-1.14.0.tar.gz
  • Upload date:
  • Size: 13.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for qrcody-1.14.0.tar.gz
Algorithm Hash digest
SHA256 6f537249a60db6b44fec5cb1f96b8e074407dd4580fbad39076ed6cac373432a
MD5 ca3e71a8ee657f0e3a0eca8e445f0939
BLAKE2b-256 fe94e2bf93f8d5279f34ee1fba38ee3d9d68dc0952cda148a252fc3a6d1ce907

See more details on using hashes here.

File details

Details for the file qrcody-1.14.0-py3-none-any.whl.

File metadata

  • Download URL: qrcody-1.14.0-py3-none-any.whl
  • Upload date:
  • Size: 17.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for qrcody-1.14.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6b01695f75ac0f3803dc1cb2b75edd61eaa4a5b84bae0154f9d4b262224b9de0
MD5 0f62914d214fd7238e67060a34669026
BLAKE2b-256 a2e0ba6c564804b61b7168fced982dd37da3713aac44751ef35a2d2f94f7b2f0

See more details on using hashes here.

Release history Release notifications | RSS feed

1.14.2

2 files

1.14.1

2 files

This release

1.14.0 This release

2 files

1.13.0

2 files

1.12.1

2 files

1.12.0

2 files

1.11.3

2 files

1.11.2

2 files

1.11.1

2 files

1.8.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page