Pretty-printing wrappers around rich
Originally part of the MPyTools package
pip install mrichIf you want to use mrich in Jupyter notebooks, it is recommended to patch the rich installation to reduce the padding around HTML elements:
python -c "import mrich; mrich.patch_rich_jupyter_margins()"mrich offers convenient shortcuts for console CLI via a Python API. The module can be imported as a whole to allow access to all the wrappers.
Below is a demonstration of all the main features of mrich:
import mrich
# large header banner
mrich.h1("Welcome to mrich")
# Regular & rich text printing
mrich.print("mrich offers a simple print wrapper which plays nicely with live rich elements")
mrich.print("Emphasis can be placed with different mrich functions:")
mrich.bold("bold text")
mrich.italic("italic text")
mrich.underline("underlined text")
mrich.print("rich markup is also [bold green]supported[reset] via square-bracket syntax")
# smaller header banner
mrich.h2("Event logging function")
# Successes, errors, and warnings
mrich.success("Success statements are the most eye-catching to the user")
mrich.error("Error statements are also highlighted")
mrich.warning("As are warnings")
# Other pre-made styles:
mrich.debug("Inobtrusive debug statements")
mrich.prompt("Eye-catching prompt")
mrich.reading("this_file_is_being_read.txt")
mrich.writing("this_file_is_being_written.txt")
mrich.disk("this_file_is_being_munged.txt", prefix="Modifying")
# Format variables:
mrich.var("variable", "value")
mrich.var("#samples", 123)
mrich.var("frequency", 12.7, "GHz")
mrich.var("file", '/example/path/file.html')
mrich.var("green number", 456, separator=":", color="green")
# smaller section separator/header
mrich.h3("This is a smaller header panel")
# dynamic elements
import time
with mrich.clock("Waiting for something"):
time.sleep(1)
with mrich.loading("Loading"):
time.sleep(1)
mrich.print("Interruptions don't disrupt live elements")
time.sleep(2)
with mrich.spinner("Spinning"):
time.sleep(1)
for i in mrich.track(range(20), prefix="tracking progress", total=20):
time.sleep(0.2)
if i == 9:
mrich.print("halfway there!")
mrich.set_progress_field("i_halfway", i)
# tabular data
import pandas as pd
df = pd.DataFrame([
dict(a=1,b=2),
dict(a=2,b=3),
dict(a=3,b=4),
dict(a=4,b=5),
])
mrich.print("This is a dataframe printed as a rich.Table", df)
raise ValueError("rich formatted traceback is enabled by default")
For use cases like Django where output needs to be routed through Python's standard logging module (e.g. for per-module filtering, file handlers, or centralized log config), mrich provides a parallel API via get_logger:
from mrich import get_logger
logger = get_logger(__name__)
logger.h1("Welcome to mrich")
logger.print("Regular message")
logger.bold("bold text")
logger.success("It worked")
logger.error("Something failed")
logger.warning("As are warnings")
logger.debug("Inobtrusive debug statements")
logger.var("count", 42)
for i in logger.track(range(20)):
...get_logger(name) behaves like logging.getLogger(name) (repeated calls with the same name return the same object) and wraps it in an MrichLogger. Each mrich function (print, bold, italic, underline, success, error, warning, debug, prompt, reading, writing, disk, var, h1, h2, h3, header) is available as a method that emits a logging.LogRecord instead of printing directly:
warning→WARNING,error→ERROR,debug/var→DEBUG, everything else →INFO- Standard logging semantics apply: level filtering, handlers, propagation, and
logging.config.dictConfigall work as expected - Each record carries the styled Rich renderable so that Rich-aware handlers keep full formatting, while plain handlers still get a sensible message
Interactive-only features (track, spinner, loading, clock, set_progress_field, increment_progress_field) still render live on the console via MrichLogger and do not produce log records — clock is the one exception, which logs its completion message.
If a logger obtained via get_logger has no handler configured (and none of its ancestors do either), an mrich.logging.MrichHandler is attached automatically so console output works out of the box. For custom setups (e.g. file logging or Django's LOGGING dict), configure handlers/formatters as usual:
import logging
from mrich.logging import MrichHandler, PlainTextFormatter
logger = logging.getLogger("myapp")
logger.addHandler(MrichHandler()) # Rich-styled console output
file_handler = logging.FileHandler("myapp.log")
file_handler.setFormatter(PlainTextFormatter("%(asctime)s %(levelname)s %(message)s"))
logger.addHandler(file_handler) # plain text, styling strippedAdditional packages are recommended for development:
pip install pre-commit black pytest
Some unit tests are available:
cd tests
pytest