Skip to content

konstantinjdobler/print-on-steroids

Repository files navigation

print-on-steroids 🏋️‍♂️

Build Status Conda Version PyPI Version Code Size Code Style Linter

A lean and hackable rich logger and drop-in enhanced replacement for the native print function.

Installation

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.

Features

  • Support for logging only on rank zero in distributed setups (e.g. DistributedDataParallel or sharded training in Deep Learning)
  • Gracefully handles tqdm and tqdm.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 and package modes when publishing packages to PyPI (cleaner logs without clutter)

Usage

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...

About

A lean and hackable rich logger and print function

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages