Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mrich

Pretty-printing wrappers around rich

Originally part of the MPyTools package

Installation

pip install mrich

If 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()"

Usage

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")
image

Logging integration

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:

  • warningWARNING, errorERROR, debug/varDEBUG, everything else → INFO
  • Standard logging semantics apply: level filtering, handlers, propagation, and logging.config.dictConfig all 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 stripped

Development

Additional packages are recommended for development:

pip install pre-commit black pytest

Some unit tests are available:

cd tests
pytest

About

Pretty-printing wrappers around Rich

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages