API reference¶
The public API of cuere. Everything here is re-exported from the top-level
cuere package (see cuere.__all__); the canonical module is shown for each
symbol. Each entry is rendered from its source docstring.
Terminal API¶
The high-level entry points.
render ¶
Encode data (unless it is already a QRMatrix) and render it.
dark / light customize ANSI mode's module colors (see
cuere.render.render_matrix); they are only valid for mode="ansi".
Example:
show ¶
show(data, *, mode=RenderMode.HALF, invert=False, out=None, width=None, on_too_wide='error', force=False, dark=None, light=None, **options)
Render data and write it to out (default sys.stdout).
The fit check is width-only: wrapping destroys a code, but a code taller
than the terminal merely scrolls and stays scannable, so height is not
gated here (use fits for a height-aware predicate).
ANSI mode silently falls back to HALF when NO_COLOR is set or the
stream is not a tty, unless force=True: raw SGR codes in logs or
pipelines are worse than a theme-dependent code. dark / light
customize ANSI mode's colors (only valid for mode="ansi"); when ANSI
falls back, they are dropped with it so a no-color terminal gets plain glyphs.
Example:
fits ¶
Whether the rendered code fits the terminal in both dimensions.
Width is the hard constraint (wrapping destroys a scan); height is checked
too because a code taller than the screen scrolls out of view. width
and height default to the current terminal size.
Example:
SupportsWrite ¶
Bases: Protocol
A text sink: any object with a write(str) method.
show writes a single string and probes isatty defensively via
getattr, so it needs only this much of a stream — sys.stdout,
io.StringIO, and minimal write-only wrappers all qualify. This is
deliberately narrower than typing.IO[str].
Example:
import io
from cuere import show
buf = io.StringIO() # any object with .write(str) is a SupportsWrite
show("HELLO", out=buf)
captured = buf.getvalue()
Matrix & encoding¶
QRMatrix
dataclass
¶
Immutable QR module matrix with the quiet zone baked in.
modules rows must be rectangular; True is a dark module.
Example:
from cuere import QRMatrix, render
m = QRMatrix.encode("HELLO") # build the matrix once
print(m.version, m.width, m.height)
print(render(m)) # render a pre-built matrix
print(render(m.inverted())) # dark/light flipped
encode
classmethod
¶
Encode data into a QR matrix.
boost_error is off by default on purpose: segno would otherwise
silently raise the error-correction level when space allows, growing
the module count for no benefit on a screen.
ECLevel ¶
Bases: StrEnum
QR error-correction level.
L is the default everywhere in cuere: codes shown on screens are not
subject to physical damage, and lower correction means fewer modules, so
the code fits a terminal (this matches what Claude Code CLI does).
Example:
from cuere import ECLevel, render
render("HELLO", error=ECLevel.M) # more robust, slightly larger code
Rendering¶
RenderMode ¶
Bases: StrEnum
How a QR matrix is turned into text.
Example:
HALF
class-attribute
instance-attribute
¶
Unicode half-blocks, 1 column x ½ row per module (default).
BLOCK
class-attribute
instance-attribute
¶
Two full-width chars per module: most robust glyphs, twice as wide.
ANSI
class-attribute
instance-attribute
¶
HALF glyphs with forced black-on-white SGR colors: theme-proof.
render_matrix ¶
Render matrix as text; lines are equal-width, no trailing newline.
The quiet zone is rendered as part of the output (spaces / light modules) because a scanner needs it in the code's own background, not whatever the surrounding terminal happens to show.
dark / light customize the SGR colors of ANSI mode (dark modules and
the light ground respectively); they default to the theme-proof black-on-white
(palette 16 on 231). They are only valid for mode="ansi" — passing
a color for half / block raises ColorError.
Example:
render_svg ¶
Render matrix as a standalone SVG document, one module per unit.
Dark modules become a single <path> over a light background <rect>.
viewBox is the module grid, so the path coordinates stay small integers;
width/height scale it to scale pixels per module.
shape-rendering="crispEdges" keeps module borders sharp (anti-aliasing
blur hurts scanning). invert flips dark and light via
matrix.inverted() — the same single code path the glyph renderers use.
Example:
render_width ¶
render_height ¶
A terminal color for ANSI mode's dark / light modules. One of:
- a name — one of the 16 standard ANSI colors (
"black","red", …,"white"and their"bright_*"variants), matched case- and separator-insensitively; - a palette index — an int in 0–255 (the xterm 256-color cube), or its
decimal string form (
"16"); - a truecolor value — a
"#rrggbb"/"#rgb"hex string, an(r, g, b)tuple of 0–255 ints, or its"r,g,b"string form.
A malformed color raises ColorError.
from cuere import render
render("HI", mode="ansi", dark="cyan", light="black") # named
render("HI", mode="ansi", dark=16, light=231) # palette index
render("HI", mode="ansi", dark="#00ffaa", light=(0, 0, 0)) # truecolor
Output formats¶
OutputFormat ¶
Bases: StrEnum
A target format for render_bytes / save.
Example:
import io
from cuere import OutputFormat, save
stream = io.BytesIO()
save("HELLO", "out.svg") # inferred from the suffix
save("HELLO", stream, format=OutputFormat.SVG) # a stream has no suffix, be explicit
render_bytes ¶
render_bytes(data, *, format=OutputFormat.TEXT, mode=RenderMode.HALF, invert=False, scale=DEFAULT_SCALE, **options)
Encode data and render it to bytes in format.
mode selects the glyphs for the text format and is ignored by the
image formats; scale is pixels-per-module for svg/png and is
ignored by text. Encoding keywords (error/border/…) apply only
when data is not already a QRMatrix.
Example:
save ¶
save(data, dest, *, format=None, mode=RenderMode.HALF, invert=False, scale=DEFAULT_SCALE, **options)
Render data and write the bytes to dest.
dest is a filesystem path or an open binary stream. When format is
omitted it is inferred from a path's suffix (.txt/.svg/.png); a
stream needs an explicit format. Unknown formats and unguessable
destinations raise UnknownFormatError.
Example:
SupportsWriteBytes ¶
Bases: Protocol
A binary sink: any object with a write(bytes) method.
The byte-oriented counterpart to cuere.terminal.SupportsWrite;
sys.stdout.buffer, io.BytesIO, and an open binary file all qualify.
Runtime-checkable so save can tell a stream from a path — neither
str nor os.PathLike carries a write method.
Example:
import io
from cuere import save
buf = io.BytesIO() # any object with .write(bytes) qualifies
save("HELLO", buf, format="svg")
Wallet URIs¶
bitcoin_uri ¶
Build a well-formed BIP-21 bitcoin: payment URI.
address is validated structurally (base58 or bech32/bech32m alphabet);
amount is a BTC value (see _format_amount); label and
message are free text and get percent-encoded. Parameters left as
None are omitted; an explicit empty label/message is kept as an
empty value. Invalid input raises WalletURIError.
The result is a plain str: pass it to optimize_uri (a bare
address with no query shrinks to QR-alphanumeric) and then to render /
show to draw the code.
Example:
lightning_uri ¶
Build a lightning: URI from a bech32 Lightning payload.
payload is a BOLT11 invoice (lnbc… / lntb… / …), an LNURL
(lnurl1…), or a BOLT12 offer (lno1…) — any bech32 string whose
human-readable part begins ln. It is validated structurally — a
single-case run of ASCII alphanumerics beginning ln (the bech32 charset
is a subset of that) — but its checksum is not verified, mirroring
bitcoin_uri. An empty string, a mixed-case payload, or one carrying a
: / @ / query character raises WalletURIError.
The result is a plain str. A lowercase payload composes with
optimize_uri, which uppercases the URI to QR-alphanumeric mode for a
smaller code (lightning: is SchemeCase.INSENSITIVE); pass the
result to render / show to draw it.
Example:
ethereum_uri ¶
Build an EIP-681 ethereum: native-payment URI.
address is the recipient, validated structurally as 0x + 40 hex
digits with its case preserved (it carries the EIP-55 checksum when
mixed-case). value is the amount in wei (1 ETH = 10**18 wei),
a non-negative integer uint256; gas_price is likewise in wei and
gas_limit is a gas-unit count.
chain_id (EIP-155, e.g. 1 for mainnet) is emitted as @<chain_id>.
Parameters left as None are omitted. Invalid input raises
WalletURIError.
The result is a plain str to pass to render / show. Do not
run it through optimize_uri: the EIP-55 checksum is case-significant,
so uppercasing would corrupt the address (optimize_uri already refuses
the ethereum: scheme for this reason).
Example:
erc20_transfer_uri ¶
Build an EIP-681 ERC-20 transfer URI: ethereum:<token>/transfer?….
Encodes a call to the token's transfer(address,uint256) function.
token is the ERC-20 contract address and to the recipient, both
validated as 0x + 40 hex digits with case preserved. amount is a
non-negative integer in the token's base units (its own decimals —
which this library cannot know — so no scaling is applied); it is emitted as
the uint256 argument. chain_id / gas_limit / gas_price behave as
in ethereum_uri. Invalid input raises
WalletURIError.
As with ethereum_uri, never pass the result to optimize_uri.
Example:
optimize_uri ¶
Uppercase a bech32-scheme URI when that provably shrinks its QR code.
Applied only when all of these hold: the scheme is case-insensitive
(SchemeCase.INSENSITIVE — bitcoin: or lightning:), the URI
is already entirely lowercase (so uppercasing cannot destroy significant
case), and the uppercased form is fully QR-alphanumeric (so a query string
or any other non-alphanumeric byte rules it out). Idempotent; returns the
input unchanged in every other case — including case-significant
(ethereum:, wc:) and unrecognized schemes.
Example:
scheme_case ¶
Classify uri by how optimize_uri treats its scheme's case.
The scheme is the text before the first : (compared case-insensitively,
per RFC 3986). A string with no : — hence no scheme — is
SchemeCase.UNKNOWN. Only an SchemeCase.INSENSITIVE scheme is
a candidate for optimization; see optimize_uri.
Example:
SchemeCase ¶
Bases: Enum
How a URI scheme's payload responds to case folding.
This is what decides whether optimize_uri may uppercase a URI to
reach QR alphanumeric mode (a smaller code): only an INSENSITIVE
scheme is ever folded, the other two are always returned verbatim.
Example:
from cuere import scheme_case, SchemeCase
scheme_case("lightning:lnbc1...") is SchemeCase.INSENSITIVE # True
INSENSITIVE
class-attribute
instance-attribute
¶
bech32 payload (BIP-173) — case carries no meaning, so uppercasing the
whole URI is lossless. bitcoin: and lightning: (BOLT11 / LNURL).
SIGNIFICANT
class-attribute
instance-attribute
¶
A scheme cuere knows to be case-significant — folding would corrupt it.
ethereum: (EIP-55 checksum case) and wc: (WalletConnect: a
case-significant relay protocol, a percent-encoded bridge URL, and an opaque
pairing key).
UNKNOWN
class-attribute
instance-attribute
¶
A scheme cuere does not recognize, or a string with no scheme at all.
Treated like SIGNIFICANT — never folded — because cuere cannot prove
the transform is lossless.
is_qr_alphanumeric ¶
Rich integration¶
QRCode ¶
Exceptions¶
CuereError ¶
EncodingError ¶
Bases: CuereError
Raised when data cannot be encoded as a QR code.
WidthError ¶
Bases: CuereError
Raised when a rendered QR code does not fit the available width.
from cuere import WidthError, show
try:
show("a long payload", width=10) # narrower than the code
except WidthError as exc:
print(exc.required, exc.available)
ColorError ¶
Bases: CuereError
Raised when a color argument is malformed or used where no color applies.
Carries the offending value — the bad color, or the render mode that
cannot take one (only ANSI mode is colored). The message is composed here so
call sites pass only a reason constant plus the value, never a raise-site
string literal (keeping the public exception contract a pure
CuereError, mirroring WalletURIError).
from cuere import ColorError, render
try:
render("HI", mode="ansi", dark="not-a-color")
except ColorError:
...
WalletURIError ¶
Bases: CuereError
Raised when arguments to a wallet-URI builder are invalid.
Carries the offending value; the human-readable reason is built here so
call sites never pass a message string (keeping the public exception
contract a pure CuereError, never a bare ValueError).
from cuere import WalletURIError, bitcoin_uri
try:
bitcoin_uri("not an address!")
except WalletURIError as exc:
print(exc.value) # the offending input
UnknownFormatError ¶
Bases: CuereError
Raised when an output format is unrecognized or cannot be inferred.
Like the other cuere errors, the human-readable message is composed here
so call sites pass only structured data (hint is a module constant, not
a raise-site literal): the offending value plus a hint that explains
what was expected.
from cuere import UnknownFormatError, save
try:
save("HI", "out.bmp") # unrecognized suffix
except UnknownFormatError:
...
MissingDependencyError ¶
Bases: CuereError
Raised when an output format needs an optional dependency that is absent.
Carries the format that was requested and the extra that provides
it, so the message always names the right cuere[<extra>] to install.
from cuere import MissingDependencyError, render_bytes
try:
render_bytes("HI", format="png") # raises only without the cuere[image] extra
except MissingDependencyError as exc:
print(exc.extra) # "image" (the missing extra)