Skip to main content

Terminal progress bars via decorators

Project description

⏱ timeo

Terminal progress bars for Python functions — just add a decorator.

PyPI Python License: MIT CI

✓ process_files   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  100%  12.4s
  download_data   ━━━━━━━━━━━━━━━━━━━━━━━          72%   0:00:04
  compress_output ━━━━━━                           20%   0:00:31

Why timeo?

Most progress bar libraries ask you to wrap your loops manually and manage the display yourself. timeo gets out of the way — decorate a function, iterate normally, done.

# before
for item in items:
    process(item)

# after
@timeo.track
def run(items):
    for item in timeo.iter(items):
        process(item)

Installation

pip install timeo

Usage

Basic progress bar

@timeo.track wraps any function with a live progress bar. The total is inferred automatically from the first argument with a len(). Use timeo.iter() to advance the bar on each iteration — no manual bookkeeping needed.

import timeo

@timeo.track
def process_files(files):
    for f in timeo.iter(files):
        do_work(f)

process_files(my_files)

Prefer manual control? Use timeo.advance() instead:

@timeo.track
def process_files(files):
    for f in files:
        do_work(f)
        timeo.advance()

Multiple concurrent functions

Every decorated function gets its own bar. They render together in a single live display. Finished bars collapse to a compact summary line so the output stays clean.

@timeo.track
def process_files(files):
    for f in timeo.iter(files):
        do_work(f)

@timeo.track
def download_data(urls):
    for url in timeo.iter(urls):
        fetch(url)

process_files(my_files)
download_data(my_urls)
✓ process_files   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  100%  12.4s
  download_data   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━   72%  0:00:04

Concurrent execution (threads) is fully supported — each bar tracks its own function independently.


Learn mode

Add learn=True and timeo will remember how long your function takes across runs, building an EMA (exponential moving average) of its runtime. Instead of counting steps, the bar fills over the expected duration.

@timeo.track(learn=True)
def run_pipeline(data):
    heavy_computation(data)
    more_work(data)
Run Behaviour
First Indeterminate spinner with run_pipeline (learning...) label
Subsequent Determinate bar filling over the expected duration
After code change Cache invalidates automatically — learning restarts

The cache key is a hash of the function's bytecode — not its name — so renaming a function preserves its history, and changing its implementation resets it.

By default timing data is stored in your platform's user cache directory (e.g. ~/Library/Caches/timeo/timings.json on macOS). Use cache="project" to store it in .timeo/timings.json relative to the current directory instead — useful for per-project isolation or sharing timings with a team via version control:

@timeo.track(learn=True, cache="project")
def run_pipeline(data):
    ...

Note: If using cache="project", add .timeo/ to your .gitignore unless you intentionally want to commit timing data.

cache= Location Best for
"user" (default) ~/.cache/timeo/timings.json Personal scripts, cross-project reuse
"project" .timeo/timings.json Per-project isolation, shared team timings

Explicit display control

The live display starts and stops automatically in most cases. For complex scripts with branching logic or long-running setup, use timeo.live() to pin the display lifetime explicitly:

with timeo.live():
    process_files(my_files)
    download_data(my_urls)
    # display stays open until the with-block exits

How it works

Piece Role
@timeo.track Wraps the function, infers total from Sized args, manages the task lifecycle
ProgressManager Singleton owning the rich live display; reference-counted so it tears down only when all tasks finish
TrackedTask Dataclass holding per-function progress state
timeo.iter() Thin generator wrapper that calls advance() on each item
ContextVar Ensures timeo.advance() always updates the right bar, even across threads

The display is built on rich.progress and rich.live.


Built with rich · MIT License

Project details


Download files

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

Source Distribution

timeo-0.3.0.tar.gz (32.6 kB view details)

Uploaded Source

Built Distribution

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

timeo-0.3.0-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for timeo-0.3.0.tar.gz
Algorithm Hash digest
SHA256 5accfe84ccf5c4d1b9983b7924a9d70b96e1f714d910f406dd9f5768d8f52505
MD5 4bcc620a29fbf74336be4f8e0f157902
BLAKE2b-256 e9c95f89220672b3f1206deaa379bbeb8a7fcbac62c7e4633ed86ab97ca30268

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on wtewalt/timeo

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

File details

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

File metadata

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

File hashes

Hashes for timeo-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d4169bce882209da6ad4ff2742f77976f12373112db00432979456c3521fb697
MD5 6c86a0bcb7089e784f30f26b5ca48f24
BLAKE2b-256 78fc0a97daa6752378f6acc393af39340c0579ab487cf8bc3e9b8d9645b35c0c

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on wtewalt/timeo

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

Supported by

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