The command line¶
The wheel ships the rich command line of this repository (the Rust port of
rich-cli), with the commands and
options of the rich binary (all but rich record; see
below):
The console script is rich-rs, because rich is rich-cli's command. Both
forms run the same code as the rich binary built from the same source, so
their output, errors and exit statuses are the binary's, byte for byte (the
tests compare them). See the CLI reference for the commands and
options.
Python rich has no command line of its own; this page is about rich-cli's.
From a script¶
The command line writes to the process's standard output and error and reads its standard input, so a script runs it as a child process and captures what it prints:
import subprocess
import sys
result = subprocess.run(
[sys.executable, "-m", "rs_rich", "--print", "[bold]Hello[/] from [i]rs_rich[/]"],
capture_output=True,
text=True,
)
print(result.stdout, end="")
print("exit status", result.returncode)
Output that is not a terminal is plain text; FORCE_COLOR=1 in the child's
environment keeps the colour. Input comes on standard input with -:
result = subprocess.run(
[sys.executable, "-m", "rs_rich", "--json", "-", "--width", "30"],
input='{"name": "rich", "values": [1, 2.5, true, null]}',
capture_output=True,
text=True,
)
print(result.stdout, end="")
Errors go to standard error, with the binary's exit statuses (2 for a usage error, 3 for input that cannot be read):
result = subprocess.run(
[sys.executable, "-m", "rs_rich", "--no-such-option"],
capture_output=True,
text=True,
)
print(result.stderr, end="")
print("exit status", result.returncode)
Interactive commands¶
choose, filter, input, confirm, pager, write, file, color and
asset run the
interactive components from a shell script. The answer goes
to standard output and the component paints on standard error, so
choice=$(python -m rs_rich choose a b c) works. Exit statuses: 0 answered
(for confirm, yes), 1 cancelled (for confirm, no), 130 Ctrl+C, 2 a usage
error, 3 no answer without a terminal.
Without a terminal they degrade: filter prints the lines matching
--value, best first (a fuzzy grep), choose from standard input answers
with --selected, as does file, write prints what standard input held,
and input, confirm, color, asset and choose from arguments ask line
by line on standard error.
lines = "src/lib.rs\nsrc/main.rs\ndocs/maintenance.md\nCargo.toml\n"
for args in (["filter", "--value", "main"], ["choose", "--selected", "Cargo.toml"], ["choose"]):
result = subprocess.run([sys.executable, "-m", "rs_rich", *args], input=lines,
capture_output=True, text=True)
print(args[0], result.returncode, result.stdout.split())
result = subprocess.run([sys.executable, "-m", "rs_rich", "confirm", "Deploy?"], input="n\n",
capture_output=True, text=True)
print("confirm", result.returncode, repr(result.stderr))
filter 0 ['src/main.rs', 'docs/maintenance.md']
choose 0 ['Cargo.toml']
choose 3 []
confirm 1 'Deploy? [y=Yes, n=No]: '
for args, answer in ((["write"], "line one\nline two\n"), (["color", "--format", "rgb"], "#ff8800\n"),
(["asset", "--kind", "box"], "rounded\n"), (["file", "--selected", "notes.md"], "")):
result = subprocess.run([sys.executable, "-m", "rs_rich", *args], input=answer,
capture_output=True, text=True)
print(args[0], result.returncode, result.stdout.splitlines())
rs_rich.cli.main¶
Runs the command line and returns its exit status. It does not call
sys.exit; python -m rs_rich and rich-rs do that with its result.
main(), with noargv, is the entry point: the arguments aresys.argv[1:], and the command line runs in this process with the GIL released. Python'ssys.stdoutandsys.stderrare flushed before and after, so output interleaves in order. For the run, Ctrl-C has its default action, ending the process as it ends the binary; Python's handler is put back afterwards.main(argv), with a list of argument strings (without the program name), is the call for a running program. The command line runs in a childpython -m rs_richprocess that shares this one's standard input, output and error, so the output lands in the same place. It is a child because the command line keeps process-wide state no library call should leave behind:--batch,--watchand the demo install a Ctrl-C handler that replaces Python's and can be installed only once per process (a config file can turn those modes on without any flag), and a few error paths end the process.
Neither form captures output: to capture it, run the command line with
subprocess as above.
The build includes the default features of the rich binary but one: URL
fetching (rich-rs https://…), images, GIFs and micro assets, Mermaid
diagrams drawn as text, and the interactive commands. rich chart,
rich dot, rich deps and rich schema are in every build. rich record
is not: its recorder runs the rich binaries beside the running executable,
which in a wheel is Python. The lumis highlighter and the mmdc Mermaid
backend are not in the wheel's command line either.