Skip to main content
        .--:--.          c o d e c h u
       /  12   \           ╔═════════╗
      |9   ●---3|  meter   ║ 00:42.7 ║   ETA  03:18
       \   6   /           ╚═════════╝
        '-----'          ─── tick · tock · tick · tock ───

Stopwatch, rolling-rate, and ETA — time things without lying about them.

codechu-meter

Stdlib-only measurement primitives — stopwatch, rolling-window rate estimator, ETA predictor — extracted from the Disk Cleaner toolchain. Zero dependencies. Python 3.10+.

Install

pip install codechu-meter

API

Stopwatch

from codechu_meter import Stopwatch

with Stopwatch() as sw:
    do_work()
print(sw.elapsed)  # → float seconds

# Manual form
sw = Stopwatch().start()
do_work()
sw.stop()
print(sw.elapsed)

Formatting is up to you. If you want pretty output, pair with codechu-fmt:

from codechu_fmt import format_duration
print(format_duration(sw.elapsed))  # → '1m 30s'

RateEstimator

from codechu_meter import RateEstimator

re = RateEstimator(window_seconds=1.0, unit="bytes")
for chunk in stream:
    re.observe(len(chunk))
print(re.rate())   # float per-second

unit is just an attribute — it never affects the numeric rate(). Use it as a label when formatting:

from codechu_fmt import format_rate
print(format_rate(re.rate(), unit=re.unit))  # → '1.2 MB/s'

ETAEstimator

from codechu_meter import ETAEstimator

eta = ETAEstimator(total=1000, mode="ema", alpha=0.3)
for current in progress:
    eta.update(current)
    remaining = eta.eta()  # float seconds or None

mode='linear' (default) uses overall throughput since construction. mode='ema' blends an exponential moving average of recent throughput for smoother numbers on bursty workloads. The alpha parameter (default 0.3) controls EMA reactivity: higher values weight recent samples more heavily.

eta() returns None until at least two updates with measurable elapsed time and positive progress.

Counter (v0.3.0+)

Thread-safe int counter. inc / dec / reset / .value are all guarded by a threading.Lock.

from codechu_meter import Counter

inflight = Counter()
inflight.inc()
try:
    serve(req)
finally:
    inflight.dec()
print(inflight.value)

Histogram (v0.3.0+)

Bucketed distribution counter. Upper edges are inclusive; values above the largest edge fall into a math.inf overflow bucket. Thread-safe.

from codechu_meter import Histogram

hist = Histogram([0.01, 0.05, 0.1, 0.5, 1.0])
for r in requests:
    hist.observe(r.latency_seconds)
print(hist.counts, hist.total)

PercentileEstimator (v0.3.0+)

Streaming p50 / p95 / p99 via Vitter's reservoir sampling (max_samples capped). Pure stdlib — no numpy. Thread-safe.

from codechu_meter import PercentileEstimator

pe = PercentileEstimator(max_samples=5_000)
for r in requests:
    pe.observe(r.latency_seconds)
print(pe.p50, pe.p95, pe.p99)

Stopwatch named sections (v0.3.0+)

Stopwatch.section(name) accumulates sub-timings into Stopwatch.sections. Same name re-entered → values add. Not thread-safe; use one Stopwatch per thread.

sw = Stopwatch().start()
with sw.section("parse"):
    parse(buf)
with sw.section("emit"):
    emit(result)
sw.stop()
print(sw.sections)  # → {"parse": 0.012, "emit": 0.004}

Design

  • Zero dependencies. Stdlib only.
  • Monotonic clock. Wall-clock jumps don't break timing.
  • No formatting coupling. Numeric primitives only; pair with codechu-fmt (or roll your own) for display strings.
  • Defensive. Zero progress, zero elapsed, NaN, and negative rates never raise.

Migrating from 0.1.x

__str__ methods were removed in 0.2.0. Replace print(sw) / str(re) / str(eta) with explicit calls:

# Before (0.1.x)
print(sw)
print(re)
print(eta)

# After (0.2.x)
from codechu_fmt import format_duration, format_rate
print(format_duration(sw.elapsed))
print(format_rate(re.rate(), unit=re.unit))
v = eta.eta()
print(format_duration(v) if v is not None else "?")

Tests

pip install -e ".[dev]"
pytest -q

Coverage gate: ≥90 %. Tests drive time via monkeypatching time.monotonic for deterministic assertions.

Documentation

  • API reference — every public symbol, parameter, return value, and exception.
  • Migration guide — 0.1.x → 0.2.0 (breaking __str__ removal, new alpha parameter, dropped codechu-fmt dependency).
  • Recipes — patterns for timing blocks, tracking download speed, computing ETA, tuning EMA alpha, and pairing with codechu-fmt.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codechu_meter-0.3.0.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codechu_meter-0.3.0-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file codechu_meter-0.3.0.tar.gz.

File metadata

  • Download URL: codechu_meter-0.3.0.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for codechu_meter-0.3.0.tar.gz
Algorithm Hash digest
SHA256 bfca71fb3b0d45f64a75f99e53672a5cb64651935f0a69ad8fb1e224ec7bcba5
MD5 324bd25ad9ed7ef2fa32a281eded9784
BLAKE2b-256 42f2b87abdd8f007fa99a5215f42181f91a6e49269ad520c6974270a7759537e

See more details on using hashes here.

Provenance

The following attestation bundles were made for codechu_meter-0.3.0.tar.gz:

Publisher: release.yml on codechu/meter-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codechu_meter-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: codechu_meter-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 11.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for codechu_meter-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8ce94451b99fcf4aa3224aa6f3810c7c6cedbd52368e2efb7228ddef449a15e9
MD5 a2290fbf672737b12c1464cf102aa62b
BLAKE2b-256 76509447d1c1971672676f7ec4e254dd997f01449f0ddc23e461f644a9f5a0c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for codechu_meter-0.3.0-py3-none-any.whl:

Publisher: release.yml on codechu/meter-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page