One-line progress + logging for humans.
Project description
humanlog
One-line logging + progress for humans.
Works in terminals, CI, and Jupyter — no setup, no configuration.
from humanlog import log
log.step("Downloading data")
...
log.done(rows=120_000)
log.info("Cleaning finished")
log.warn("Missing values detected", cols=3)
Why humanlog?
Most logging tools are either:
- too low-level (stdlib logging),
- too heavy (structured logging frameworks),
- or great at one thing (progress bars) but awkward for everything else.
humanlog is opinionated and small:
- readable output
- automatic timing
- graceful behavior everywhere
- zero configuration
It’s for applications, scripts, CLIs, and data workflows.
Install
pip install humanlog
Python 3.9+ (no dependencies).
The core idea
Steps feel like steps
log.step("Training model")
train()
log.done(loss=0.031)
Output (terminal):
→ Training model …
✓ Training model (loss=0.031, time=2.41s)
No manual timers. No formatting. No state.
Informational messages
log.info("Loading dataset", rows=120_000)
log.warn("Missing values detected", cols=3)
log.error("Failed to connect to database")
Output:
[12:40:03] ℹ Loading dataset (rows=120000)
[12:40:04] ⚠ Missing values detected (cols=3)
[12:40:05] ✖ Failed to connect to database
Works everywhere
Terminal (TTY)
- Animated steps
- Clean overwrite
- Human-friendly symbols
CI (GitHub Actions, GitLab, etc.)
- No carriage-return garbage
- Timestamped, line-by-line logs
Jupyter notebooks
- No broken progress bars
- Clean output cells
humanlog automatically detects where it’s running and adapts.
Set HUMANLOG_NO_ANIMATE=1 (or NO_COLOR=1) to force non-animated output.
Zero configuration
No handlers.
No log levels to wire up.
No global logging side effects.
Just import and go.
API
log.step(message: str)
Start a timed step.
If another step is already active, humanlog automatically finishes it first so
you never end up with overlapping step state.
You can also use it as a context manager to auto-complete the step:
with log.step("Training model"):
train()
If an exception escapes the block, the step is automatically closed as failed:
[12:40:05] ✖ Training model (error=RuntimeError, time=0.73s)
log.done(**info)
Finish the current step and print timing + optional key/value info.
log.info(message: str, **info)
Print an informational message.
If a step is active, it is automatically completed before the info line is printed.
log.warn(message: str, **info)
Print a warning (to stderr).
If a step is active, it is automatically completed before the warning is printed.
log.error(message: str, **info)
Print an error (to stderr).
If a step is active, it is automatically completed before the error is printed.
Key/value info is always optional and rendered inline:
log.info("Loaded batch", batch=3, rows=1024)
Example: a real script
from humanlog import log
log.step("Downloading data")
download()
log.done(rows=120_000)
log.step("Cleaning data")
clean()
log.done(dropped=341)
log.step("Training model")
train()
log.done(epochs=10, loss=0.031)
log.info("All done")
Readable. Intentional. Calm.
Non-goals (by design)
humanlog is not:
- a replacement for structured logging
- a metrics system
- a tracing framework
- a progress-bar DSL
If you need JSON logs or OpenTelemetry, use those tools.
If you want pleasant, readable output, use humanlog.
Roadmap (likely, but optional)
log.track(iterable, label="Processing")- optional Rich-powered rendering
- stdlib logging bridge (opt-in)
The core will stay small.
Philosophy
humanlog optimizes for:
- clarity over flexibility
- defaults over configuration
- humans over machines
Logs are for people first.
Contributing
Contributions are welcome. See CONTRIBUTING.md for local setup and quality checks.
Changelog
Release history is tracked in CHANGELOG.md.
Releasing
Maintainers can follow RELEASE.md for packaging, verification, and publish steps.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file humanlog-0.1.0.tar.gz.
File metadata
- Download URL: humanlog-0.1.0.tar.gz
- Upload date:
- Size: 10.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f35ea0436c434cf0bc85325dbaf3de514096e5ac48866946bdd2ec6ee93afd03
|
|
| MD5 |
88aa1270998f818692b4f2f738582d95
|
|
| BLAKE2b-256 |
415fe6cc31a3f9fb240df0493390cf1505387cdf11c497336e283ef39c7ecd2e
|
File details
Details for the file humanlog-0.1.0-py3-none-any.whl.
File metadata
- Download URL: humanlog-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2b9ef98bf877a375aeb66061e6908c6ba159c2c6a333ed924ba9b6f5bef5076
|
|
| MD5 |
b0c564e490138d28585dc2b7b9de47ef
|
|
| BLAKE2b-256 |
011138174473fbf8eae99e921049cf40562418e18749d4740bb7042a2aac868a
|