get_logger()
|
v
+---------------------------+
| LoggingRich |
+---------------------------+
| .info .success .warning | --> Rich-formatted console
| .error .debug .rule | with auto file:line prefix
| .track .print .info_json|
+---------------------------+
plus, from the same package:
@lru_cache + DisableableLRUCache --> cached calls,
with a disable hook for tests
path_join / path_exists / path_open --> local + s3:// transparent
get_elapsed_time(seconds) --> "01d : 01h : 12m : 03s"
sha256sum(path) / get_cache_dir() --> stable on-disk caching
klogr is what you reach for when stdlib logging.basicConfig doesn't cut it and print() feels gross. It wraps Python's logging module with rich.logging.RichHandler pre-configured, adds stacklevel awareness so every line shows where it came from, and ships a handful of helpers (caching, paths, timing) that show up in every ML/data project.
Why use it
- Drop-in
get_logger()— module-scoped, cached, zero setup. Nologging.basicConfig, no handler wiring. - Stacklevel-aware — every log line auto-prefixes with the caller's
file:line. Stop hunting for which module shouted what. logger.track()— wrapsrich.progress.track()and works insideThreadPoolExecutor/ProcessPoolExecutorwithout going silent.logger.print()/logger.info_json()— pretty-print Pydantic models, dicts, JSON without piping throughprint(json.dumps(..., indent=2)).@lru_cachewith a disable hook — flip an env var to bypass caching globally (handy for tests).- Path helpers that handle S3 —
path_join,path_exists,path_mkdir, etc. work whether you pass/tmp/fooors3://bucket/foo. get_elapsed_time(seconds)— formats float seconds as00d : 01h : 12m : 03s.- One-liner dual output —
with logger.to_file("run.log"):mirrors every log line to BOTH the Rich-formatted console AND the log file. Perfect for batch jobs. - Timed blocks —
with logger.timed("train epoch"):prints entry + exit + elapsed, notime.perf_counter()boilerplate. logger.exception("msg")— like stdliblogging.exceptionbut the traceback is rendered by Rich.logger.kv(epoch=12, lr=3e-4)— one-line structured key=value logging for training loops.
Install
uv add klogr
# or
pip install klogr
Requires Python ≥ 3.10. Runtime deps: rich, pydantic, python-dotenv, beartype, jaxtyping, natsort, sha256sum.
Quickstart
from klogr import get_logger
logger = get_logger()
logger.info("loaded %d samples", 1024) # auto file:line prefix
logger.success("training converged") # green check
logger.warning("validation loss plateaued")
logger.error("OOM on batch 42")
# Pretty-print structured data
logger.print({"epoch": 12, "lr": 3e-4, "loss": 0.21})
# Progress bar that works in parallel
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=8) as pool:
for result in logger.track(pool.map(process, items), total=len(items), description="batch"):
...
What's in the box
Logger
from klogr import get_logger, LoggingRich, DEFAULT_VERBOSITY
logger = get_logger() # default verbosity
quiet = get_logger({"info": False, "debug": False}) # custom
logger.info(msg) # cyan
logger.success(msg) # green check
logger.warning(msg) # yellow
logger.error(msg) # red
logger.rule(title) # horizontal divider
logger.print(any_object) # rich.print, soft-wrap aware
logger.info_json(json_str) # syntax-colored JSON
logger.track(iter, total, description) # progress bar
Log to console AND a file at the same time
from klogr import get_logger
logger = get_logger()
# Scoped to a block — auto-restores console-only on exit:
with logger.to_file("step.log"):
logger.info("written to console AND step.log")
logger.success("step done")
# back to console-only here
# Or set/unset manually if you need broader control:
logger.enable_dual_output("training.log")
logger.info("epoch=12")
logger.disable_dual_output()
The file gets the Rich-rendered output verbatim (colors stripped on the
file side, preserved in the terminal). Check logger.is_file_enabled()
to confirm dual output is on.
Time a block
with logger.timed("train epoch"):
train_one_epoch()
# logs: ▶ train epoch
# ✓ train epoch — 00d : 00h : 12m : 03s
Structured key=value lines
logger.kv(epoch=12, lr=3e-4, loss=0.214)
# logs: epoch=12 lr=0.0003 loss=0.214 (with rich coloring)
Log an exception with a Rich traceback
try:
do_work()
except Exception:
logger.exception("do_work failed")
# logs the message at ERROR, then a syntax-highlighted traceback
Caching
from klogr import lru_cache, DisableableLRUCache, get_cache_dir, sha256sum
@lru_cache(maxsize=128)
def expensive(key: str) -> bytes:
...
# Stable on-disk paths
cache_root = get_cache_dir() # XDG cache root
digest = sha256sum("/path/to/file.bin") # hex string
Path helpers (local + S3 transparent)
from klogr.path import (
path_join, path_exists, path_mkdir, path_dirname,
path_basename, path_glob, path_is_s3, path_open,
)
path_exists("/tmp/local.bin") # True/False
path_exists("s3://bucket/key.bin") # True/False (same call)
path_mkdir("/tmp/nested/dir", parents=True, exist_ok=True)
for p in path_glob("/data/*.jpg"):
with path_open(p, "rb") as f:
...
Timing
from klogr import get_elapsed_time
print(get_elapsed_time(86400 + 3661)) # '01d : 01h : 01m : 01s'
Examples
Runnable scripts live in examples/:
01_basic_logger.py— log levels, formatting, file:line prefix02_pretty_tables.py—LoggingTablefor tabular console output03_progress_tracking.py—logger.track()in parallel workers04_caching.py—@lru_cachewith disable-hook05_path_helpers.py— local + S3 path ops
uv run examples/01_basic_logger.py
Layout
klogr/
├── __init__.py # public re-exports
├── logger.py # LoggingRich, LoggingTable, get_logger
├── cache.py # lru_cache, DisableableLRUCache, sha256sum, get_cache_dir
├── path/ # local + S3 path helpers
│ ├── __init__.py
│ ├── ops.py # pure ops (join, dirname, basename, suffix, …)
│ ├── env.py # path_dotenv, path_home, path_expanduser
│ ├── io.py # mkdir, remove, copy, move, read/write
│ └── query.py # exists, is_dir, glob, listdir, stat
└── time.py # get_elapsed_time
Build & test
uv sync
.venv/bin/pre-commit run --all-files
.venv/bin/pytest
.venv/bin/mypy klogr/
License
MIT — see LICENSE.md.
Metadata
Release files for klogr 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| klogr-0.2.1.tar.gz | 33.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| klogr-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 61.7 kB
Release files / klogr-0.2.1.tar.gz
| Download URL | klogr-0.2.1.tar.gz |
|---|---|
| Size | 33.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2054a53741bad30bd59940c3dece53757767e557c17a8340b9b7657ced801663
|
|
BLAKE2b-256 checksum How to use checksums |
cf980e1e3d15dcc9933d8291bac31206f32c1d58691380a82b47a76185e2020a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / klogr-0.2.1-py3-none-any.whl
| Download URL | klogr-0.2.1-py3-none-any.whl |
|---|---|
| Size | 28.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
40f7ea752f7bb8f3a03478ec3ed7e0430af08706229d92a4e83b1cbe5dd97b2c
|
|
BLAKE2b-256 checksum How to use checksums |
6eea0cc039ad3b3a224b35795a80ae65aae82833dc6511f69fa944abef49481c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for klogr 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.