Skip to main content

Utilities

Python 3.9+ Version Downloads

A lightweight toolkit for the plumbing every project rewrites: where settings live, how logs are set up, what a batch shows while it runs, and where the time goes. Four independent areas, one shared folder on the machine.

pip install utilities-toolkit
# or
uv add utilities-toolkit

Charts need an extra: pip install "utilities-toolkit[plot]".


What is in it

Configuration INI, JSON, YAML and Python settings under one root, reached by attribute access.
Logging One call sets up a Rich console, rotating files, and three custom levels.
Frames & sparklines Put a distribution or a DataFrame in the log, readable over SSH.
Terminal charts plotext charts at their own log level. No image, no artefact.
Probing Latency and memory instrumentation that costs nothing when off.

Full API index and cost tables: docs/.


Configuration

from utilities import Config

Config.ensure_initialized("my_project", {"PATHS": {"DATA": "/mnt/data"}})

value = Config.my_project.PATHS.DATA        # case-insensitive throughout

Files live in ~/utilities/config/ (C:/utilities/config on Windows), so several projects on the same machine share one place instead of scattering dotfiles. INI, JSON, YAML and .py are all read the same way. → docs/config.md

Logging

from utilities import LoggingConfigurator

LoggingConfigurator.configure(project="my_project", level="INFO")

Rich console, a daily-rotating my_project.log, optional JSONL, Rich tracebacks. Idempotent: calling it twice cannot stack handlers. Overridable from the environment (LOG_LEVEL, LOG_DIR, LOG_JSON…), and it understands the custom level names below.

Every format is customisable — class constants (CONSOLE_FORMAT, FILE_FORMAT, …), per-call console_formatter / file_formatter / json_formatter, extra rich_handler_kwargs, or rich_console=False for a plain stdlib StreamHandler. See docs/logging.md.

LoggingConfigurator.watch(project="my_project", module=__name__, level="DEBUG")

adds a dedicated file for one module without disturbing anything else. → docs/logging.md

Three custom levels

6   PLOT        ~1.7 ms per chart
8   DATAFRAME   ~80 µs to ~340 µs
10  DEBUG
15  PERF        ~1.15 µs per probe
20  INFO

Ordered by increasing cost as you go down: lowering the level means agreeing to pay more. Because levels are ordered, PLOT also emits DataFrames — to get one without the other, use logger namespaces (myapp.data, myapp.plot). Every helper takes the logger as its first argument so that choice stays yours.

The package never adds a handler and never touches the host's logging configuration.

Sparklines and DataFrames in the log

Start with spark(). ~12 µs for 300 points, no dependency, one line, and still greppable — 145× cheaper than a chart.

from utilities import spark, log_frame

log.info("nav n=%d %s [%.2f, %.2f]", len(nav), spark(nav), min(nav), max(nav))
nav n=300 ▂▂▂▂▂▂▁▂▃▃▃▅▅▄▅▆▆▆▇██▇▆▆ [96.32, 120.61]
log_frame(data_logger, positions, mode="describe", label="positions")

Four modes — head, tail, full, describe — with a hard row cap on full, scoped display settings, and a LazyFrame guard that logs the query plan instead of ever calling collect(). polars and pandas are supported but never imported.

A multi-line record is no longer greppable — that trade-off is the reason spark() comes first. → docs/frames.md

Terminal charts

from utilities.log.plots import plot_line
plot_line(plot_logger, nav, title="NAV")
                                     NAV
     ┌─────────────────────────────────────────────────────────────────┐
120.6┤                                                    ▐▙  ▄▖▄      │
     │                                                ▄▟  ▌▐▙▞▀▜ ▛▖    │

For a nightly batch whose log is read over SSH from a phone: no image, no artefact to fetch, the log is the only surface. Needs console_width=120 to avoid being wrapped — why. → docs/plots.md

Probing

from utilities import probed
from utilities.probe import probe, report

@probed()
def fetch_rows(cursor, sql):
    cursor.execute(sql)
    return cursor.fetchall()

with probe("materialize"):
    rows = [dict(r) for r in raw]
PROBE_TIER=1 python my_script.py
label                                  n       wall       self       wait        mean         p95
-------------------------------------------------------------------------------------------------
db.execute                             4     4.310s     4.310s     4.290s   1077.50ms   1131.02ms
transform                              1     0.412s     0.412s     0.001s    412.30ms    412.30ms
  • wait = wall - cpu — the column that decides what to do next. Close to wall, you are waiting on a database or a network share and rewriting Python will gain you nothing. Close to zero, the code is the problem.
  • self = wall - children — cProfile's tottime. A function that only delegates tops the wall ranking while being innocent.

Zero cost when off: at PROBE_TIER=0, probed() returns your function unchanged — 0.0 ns measured, no wrapper, not even a flag test. That is what makes it safe to leave in production code. The tier is read once at import and cannot be changed at runtime; that is the price of the guarantee.

Only instrument blocks of 400 µs or more, and never read latency from a PROBE_TIER=2 run — tracemalloc slows the whole process 11×. → docs/probe.md

probe tells you which block costs. To find out why, inside it:

uv run --with pyinstrument pyinstrument my_script.py

Examples

Every script in examples/ runs on its own with no arguments.

  • examples/probe/ — the three tiers side by side, the overhead measured on your machine, CPU vs I/O, nesting, asyncio, output formats
  • examples/log/ — levels and namespaces, the four frame modes, the four charts, costs, three traps, and a batch as it reads in a tail -f

Two playgrounds exist as both a notebook and a # %%-cell script: log_playground and probe_playground.

Structure

src/utilities/
├── config/      configuration store
├── log/         setup, levels, frames, plots, helpers
├── probe/       latency and memory instrumentation
└── utils/       folder helpers
docs/            full documentation
examples/        runnable demos and notebooks
tests/           test suite

Metadata

Release files for utilities-toolkit 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for utilities-toolkit 1.1.0
File Size Uploaded Provenance Actions
utilities_toolkit-1.1.0.tar.gz 30.1 kB Without provenance Details for utilities_toolkit-1.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for utilities-toolkit 1.1.0
File Interpreter ABI Platform Actions
utilities_toolkit-1.1.0-py3-none-any.whl Python 3 none any Details for utilities_toolkit-1.1.0-py3-none-any.whl

Total release size: 66.7 kB

Release files / utilities_toolkit-1.1.0.tar.gz

Download URL utilities_toolkit-1.1.0.tar.gz
Size 30.1 kB
Tags Source
SHA-256 checksum
How to use checksums
6c967ee8933c25bde252442727800692871ed6ef2af78f5fd999c15a8bea3549
BLAKE2b-256 checksum
How to use checksums
c3d7a053f80194b77847bec7a48ad1d114f08d7b236415acd8d759ab90bbd8ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / utilities_toolkit-1.1.0-py3-none-any.whl

Download URL utilities_toolkit-1.1.0-py3-none-any.whl
Size 36.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a72efcbf699b2585ee204de21efc9e76e8e0cca41e4b1c6a6892825a5d3cfa73
BLAKE2b-256 checksum
How to use checksums
b31700f010786133cf45a10fad617241be97df8880d5cf1753eea35d43d237d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for utilities-toolkit 1.1.0

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page