QRpen
QRpen is a dependency-free Python 3.13+ QR encoder and renderer designed for embedding in applications, agent prompts, terminals, custom-URI workflows, and file-export pipelines. The Python API is the primary interface; the qrpen command is a thin adapter over it.
Highlights
- Dependency-free runtime; no external QR library.
- Automatic QR version selection from payload size (versions 1–10).
- Low, medium, quartile, and high error correction.
- Exact UTF-8 payload preservation: custom URI schemes are not parsed, normalized, decoded, or rebuilt.
- Optional companion instruction that is returned with the artifact but never encoded into the QR.
- Plain text, Markdown, agent-hook/prompt, terminal, PNG, and SVG output.
- Responsive SVG: the root uses
viewBoxonly; no fixedwidthorheightattributes. - Configurable text character-cell ratio and PNG pixels-per-module scale.
- Structured size metadata in characters, pixels, viewport units, or QR modules.
- ANSI truecolor terminal rendering with CSS color names and
#RRGGBB. - Side-effect-free embedding API; filesystem/stdout behavior is confined to adapters.
Installation
python -m pip install .
For development:
python -m pip install -e '.[test]'
CLI quick start
qrpen 'https://example.com'
qrpen 'arrow://auth?id=abc' --frame --no-color
qrpen 'arrow://auth?id=abc' --output-format hook
qrpen 'https://example.com' --output-format svg --output-file qr.svg
qrpen 'https://example.com' --output-format png --scale 12 --output-file qr.png
txt with no output file preserves the interactive terminal renderer. md, hook, and other textual portable formats go to stdout unless --output-file is supplied. Binary PNG requires --output-file.
Size inspection
Use --size to calculate the produced dimensions without emitting the artifact:
qrpen 'https://example.com' --output-format txt --size
qrpen 'https://example.com' --output-format hook --size
qrpen 'https://example.com' --output-format svg --size
qrpen 'https://example.com' --output-format png --scale 4 --size
Units are format-specific:
| Format | Size unit | Meaning |
|---|---|---|
txt |
characters | proportional QR matrix width × rows |
md |
characters | QR matrix geometry (fence excluded from measurement) |
hook |
characters | complete generated prompt payload geometry |
svg |
viewport | SVG viewBox dimensions |
png |
pixels | actual raster dimensions |
The encoded QR matrix itself is always square and available through QrCode.size / artifact module_count.
Python API
from qrpen import ExportOptions, OutputFormat, QrApi, QrRequest
request = QrRequest(
content="arrow://auth?id=a%2Fb&next=x%3Fy%3D1",
instruction="Authenticate and open the URI exactly as supplied.",
)
artifact = QrApi.render_artifact(
request=request,
output_format=OutputFormat.hook,
options=ExportOptions(ratio=2.6),
)
assert artifact.encoded_content == request.content
print(artifact.size)
print(artifact.content)
The instruction is metadata/presentation content. It does not change QR capacity and is not encoded into the QR matrix.
PNG
artifact = QrApi.render_artifact(
request=QrRequest(content="https://example.com"),
output_format=OutputFormat.png,
options=ExportOptions(border=4, scale=10),
)
assert artifact.size.unit.value == "pixels"
Responsive SVG
artifact = QrApi.render_artifact(
request=QrRequest(content="https://example.com"),
output_format=OutputFormat.svg,
)
The SVG root resembles:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 29 29">
There are intentionally no root width or height attributes. Size it with CSS or the embedding viewport.
Terminal
from qrpen import QrApi, QrRequest, TerminalOptions
text = QrApi.render_terminal(
request=QrRequest(content="arrow://auth?id=abc"),
options=TerminalOptions(
frame=True,
frame_color="dodgerblue",
qr_foreground="black",
qr_background="white",
),
)
The API returns the string. It does not print it.
Prompt / hook mode
Hook output is designed for session-start context systems. It contains a strict instruction asking the receiving agent to reproduce the framed QR exactly once before its first normal response. This is instruction-driven behavior: the receiving model/UI ultimately controls whether and how it is displayed.
Agent/surface calibrations keep that presentation renderer-specific. Codex and Claude Code CLI sessions use explicit text ratios so monospaced shell cells remain scannable. Their desktop chat surfaces use a generated PNG instead, because proportional chat typography cannot preserve QR module geometry.
qrpen 'arrow://auth?id=abc' \
--instruction 'Authenticate using this URI.' \
--output-format hook > session-start.txt
This is equivalent to --output-file session-start.txt for textual output.
Custom URI safety
QRpen treats content as opaque Unicode text and encodes content.encode("utf-8"). It deliberately does not call a URL parser. Consequently percent escapes, query separators, custom schemes, and Unicode are preserved exactly at the byte-encoding boundary.
If URI canonicalization, signing, authentication, expiry, privilege escalation, or replay protection is required, implement those semantics in the URI-producing/consuming layer. QRpen is the transport/representation layer, not an authorization system.
Validation and errors
Public configuration errors derive from QrpenError. Important subclasses are:
QrConfigurationError— invalid ratio, border, scale, or empty content.QrEncodingError— encoding failure.QrCapacityError— payload exceeds the supported QR capacity.QrRenderError— reserved for rendering failures.
Output sizing
QR version determines the logical module matrix: 17 + 4 × version. Text ratio changes only horizontal character representation; it never changes encoded data. PNG scale is pixels per QR module. SVG uses logical cells directly in its viewBox.
Architecture
QrRequest / ExportOptions / TerminalOptions
│
▼
QrApi
┌──────────┼──────────┐
▼ ▼ ▼
encoder renderers measure
│ │ │
└──────────┴──────────┘
│
▼
QrArtifact
CLI = argument parsing + stdout/file adapter only
Application code should depend on qrpen public exports, not _legacy or other private implementation modules.
Testing
coverage run -m pytest
coverage report
The project config enforces a 90% coverage gate for the supported public package surface. Tests cover all output modes, exact custom-URI preservation, size metadata, responsive SVG invariants, PNG dimensions, terminal framing, CLI stdout/files, validation, error correction levels, and QR version growth.
Examples
examples/python_api.py— custom URI + companion instruction + hook artifact.examples/responsive_svg.py— responsive viewBox-only SVG.
Compatibility
- Python 3.13+
- No runtime dependencies
- UTF-8 text payloads
- QR versions 1–10
License
MIT.
Directory contents
Files
LICENSE— Provide LICENSE project content.__init__.py— QRpen public API.__main__.py— Execute QRpen aspython -m qrpen.api.py— Side-effect-free QRpen embedding API.cli.py— Thin QRpen command-line adapter.config.py— Load\[tool.qrpen\]settings from the nearestpyproject.toml.engine.py— QRpen: dependency-free QR generation for Python, prompts, and terminals.errors.py— QRpen exception hierarchy.models.py— Typed public models for QRpen.pyproject.toml— Provide pyproject toml content.
Subdirectories
examples/— Runnable examples for the qrpen package.
Metadata
Release files for qrpen 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| qrpen-1.0.0.tar.gz | 30.2 kB | Without provenance | Details for qrpen-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| qrpen-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for qrpen-1.0.0-py3-none-any.whl |
Total release size: 59.7 kB
Release files / qrpen-1.0.0.tar.gz
| Download URL | qrpen-1.0.0.tar.gz |
|---|---|
| Size | 30.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4bd96adeb207d6bcc96c15e7563d3c6b9286877397c8bfd9ac6294f95a4c7d4
|
|
BLAKE2b-256 checksum How to use checksums |
3697b2ca4d30436452872692255cf3e0c1a83e5ec38883e4f51b538a8870a370
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Release files / qrpen-1.0.0-py3-none-any.whl
| Download URL | qrpen-1.0.0-py3-none-any.whl |
|---|---|
| Size | 29.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d90856a3f1ba11d5e04fb24adb89a6167aba31027c1f32e36d13863c5f1d17f1
|
|
BLAKE2b-256 checksum How to use checksums |
8091220add4042aa52ce363f6ae653c91101559ec941cea289311e1c5ac0f2c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Security for qrpen 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.