Last Updated: 02/06/2024 @ 11:11:20
enrich
💸
Enrich adds few missing features to the wonderful rich library.
rich
🤝 logging
enrich
provides a generalized RichHandler
that allows for rich
style highlights without line breaks
🧩 Install
python3 -m pip install "git+https://github.com/saforem2/enrich"
test_logger.py
from enrich import get_logger
= get_logger(name='test', level='DEBUG')
log 'debug')
log.debug('info')
log.info('warning')
log.warning('error')
log.error('critical') log.critical(
Output
:
[2024-01-28 11:13:30][DEBUG][test_logger:24] - debug [2024-01-28 11:13:30][INFO][test_logger:25] - info [2024-01-28 11:13:30][WARNING][test_logger:26] - warning [2024-01-28 11:13:30][ERROR][test_logger:27] - error [2024-01-28 11:13:30][CRITICAL][test_logger:28] - critical
📸 Screenshots
🤷🏻♂️ Ambivalent
😻 Catpuccin Latte
😈 Doom One
💅 Styles
Dark Styles
Light Styles
⚙️ Setup
from enrich import get_logger
= get_logger(name='enrich', level='DEBUG') log
Output
'debug')
log.debug('info')
log.info('warning')
log.warning('error')
log.error('critical')
log.critical(2024-01-28 11:04:50][DEBUG][ipython:1] - debug
[2024-01-28 11:04:50][INFO][ipython:2] - info
[2024-01-28 11:04:50][WARNING][ipython:3] - warning
[2024-01-28 11:04:50][ERROR][ipython:4] - error
[2024-01-28 11:04:50][CRITICAL][ipython:5] - critical [
Alternative Setup
logging.config.dictConfig(...)
:import yaml with Path('logconf.yaml').open('r') as stream: = yaml.load(stream, Loader=yaml.FullLoader) config = logging.config.dictConfig(config) log_config = logging.getLogger(__name__) log 'INFO') log.setLevel(
Where
logconf.yaml
:--- # logconf.yaml handlers: term: class: enrich.handler.RichHandler show_time: true show_level: true enable_link_path: false level: DEBUG root: handlers: [term] disable_existing_loggers: false ...
📚 Details
↪️ Redirect support
Our Console class adds one additional option to rich.Console in order to redirect sys.stdout
and sys.stderr
streams using a FileProxy.
from enrich.console import Console
import sys
= Console(
console =True, # <-- not supported by rich.console.Console
redirect=True)
record"foo")
sys.write(
# this assert would have passed without redirect=True
assert console.export_text() == "foo"
🌯 Soft wrapping
If you want to produce fluid terminal output, one where the client terminal decides where to wrap the text instead of the application, you can now tell the Console constructor the soft_wrap preference.
from enrich.console import Console
import sys
= Console(soft_wrap=True)
console print(...) # no longer need to pass soft_wrap to each print console.
Rich logger assumes that you always have a fixed width console and it does wrap logged output according to it. Our alternative logger does exactly the opposite: it ignores the columns of the current console and prints output using a Console with soft wrapping enabled.
The result are logged lines that can be displayed on any terminal or web page as they will allow the client to decide when to perform the wrapping.
import logging
from enrich.logging import RichHandler
= "%(message)s"
FORMAT
logging.basicConfig(="NOTSET", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()]
level
)
= logging.getLogger("rich")
log "Text that we do not want pre-wrapped by logger: %s", 100 * "x") log.info(
💾 ANSI Escapes
Extends Rich Console to detect if original text already had ANSI escapes and decodes it before processing it. This solves the case where printing output captured from other processes that contained ANSI escapes would brake. upstream-404
Citation
@online{foreman2024,
author = {Foreman, Sam},
title = {`Enrich`},
date = {2024-02-06},
url = {https://saforem2.github.io/enrich},
langid = {en}
}