A lean and hackable rich logger and drop-in enhanced replacement for the native print
function.
You can install print-on-steroids
with pip
:
pip install print-on-steroids
or conda
:
conda install -c conda-forge print-on-steroids
We use the better-exceptions
package if available to pretty print tracebacks. To install better-exceptions
, use pip install print-on-steroids[exceptions]
instead or run pip install better-exceptions
manually.
- Support for logging only on rank zero in distributed setups (e.g. DistributedDataParallel or sharded training in Deep Learning)
- Gracefully handles
tqdm
andtqdm.rich
progress bars (logs during training do not interrupt the progress bar!) - A context manager and decorator for beautiful and enriched exception printing
- Rich meta-information for free like timestamps and originating line of code (turned into a clickable deeplink by VS Code)
- Easy switching between
dev
andpackage
modes when publishing packages to PyPI (cleaner logs without clutter)
print_on_steroids
- like print
but on steroids!
from print_on_steroids import print_on_steroids as print
# Enjoy enhanced print with optional log levels, timestamp, and originating line of code
print("Enhanced", "print!", level="success", print_time=True, print_origin=True)
# Logging with multiple processes - avoid terminal clutter
print("Gets printed", rank=0, rank0_only=True)
print("Doesn't get printed", rank=1, rank0_only=True)
Use logger
for more advanced use cases:
from print_on_steroids import logger
# Full-fledged logger object out-of-the-box
logger.log("This", "is", "cool", level="info")
# or give the log level directly:
logger.info("This", "is", "cool")
logger.warning("This", "is", "dangerous")
logger.error("This", "is", "fatal")
...
# Easy setup for distributed setting:
logger.config(rank=RANK, print_rank0_only=True)
# Afterwards, the rank is remembered and does not need to be passed again
logger.success("Dataset processing finished!") # <-- this now prints only on rank zero
# For cleaner logs when publishing a package, use this:
logger.config(mode="package", package_name="MyPackage")
All methods gracefully handle tqdm
- no interrupted progress bars:
from print_on_steroids import logger, print_on_steroids as print
from tqdm import tqdm
for i in tqdm(range(42), desc="This works!"):
sleep(1)
logger.success("Work done:", i)
print_on_steroids("Work done:", i)
Beautifully formatted Exception and traceback printing:
from print_on_steroids import graceful_exceptions
# As a context manager:
with graceful_exceptions():
# Do stuff...
# As a decorator:
@graceful_exceptions()
def do_stuff():
# Do stuff...