Skip to main content

Computational Stopwatch

Simple stopwatch to easily print the elapsed time of a set of operations. It's a minimalistic library, but it is very useful in many real cases.

Installation

pip install computational_stopwatch

or

conda install -c <your-anaconda-channel> computational_stopwatch

Usage

The easiest way to use this tool is in conjunction with the with python statement:

>> from computational_stopwatch import Stopwatch
>>
>> with Stopwatch():
>>  time.sleep(3) # <- simulates a computation 
Elapsed time 0:00:03.003106

Anything within the scope of the with statement will count against the elapsed time. An optional task name to be printed along the elapsed time (e.g. for better identification in a log) can be set in the constructor. This name will be prepended to the printed message. This is useful to track the elapsed time of several tasks ran in sequence.

>> with Stopwatch("My short task"):
>>  time.sleep(3) # <- simulates a computation 
My short task complete. Elapsed time 0:00:03.003106

Alternatively to the use with the with statment, the class can be directly instantiated and the print function explicitly called.

>> sw = Stopwatch()
>> time.sleep(3)
>> sw.print_elapsed_time()
Elapsed time 0:00:03.003280

or simply

>> sw = Stopwatch()
>> time.sleep(3)
>> print(sw)
0:00:03.003269

The start time can be reset with the reset_time function and the get_elapsed_time method returns the unformatted elapsed time, which is useful for numerical comparisons.

Different verbosity levels can be set in the constructor, with 2 as the default level, with 1 only the time is printed when the object is deleted, and with 0 nothing is printed. This is convenient to directly assess the elapsed time in seconds without any rogue prints on deletion:

>> sw = Stopwatch(verbosity=0)
>> time.sleep(3)
>> t = sw.get_elapsed_time()
>> print(t)
3.0032315254211426

By default, everything is printed on the standard output. Further or alternative streams can be set in the constructor. For instance, the folowing snipped:

>> log_file = open('/tmp/my_log_file.txt','w')
>> with Stopwatch("My logged task", streams=[sys.stdout, log_file]):
>>  time.sleep(3) # <- simulates a computation 
My logged task complete. Elapsed time 0:00:03.002731

prints the message both on the standard output as well as in the log file for future perusal.

Releasing

Releases are cut by pushing a git tag; nothing is published by hand.

The version lives in exactly one place, __version__ in computational_stopwatch/stopwatch.py. Both setup.py and conda-recipe/meta.yaml read it from there, so the PyPI and conda packages can never disagree about what they ship.

Release steps

  1. Bump the version in computational_stopwatch/stopwatch.py:
    __version__     = '1.0.6'
    
  2. Write the changelog entry in HISTORY.md, with a heading that matches the new version exactly:
    ## v1.0.6
    
    - what changed
    
  3. Commit onto main:
    git checkout main
    git add computational_stopwatch/stopwatch.py HISTORY.md
    git commit -m 'release v1.0.6'
    
  4. Tag and push. The tag must be v + the version from step 1:
    git tag -a v1.0.6 -m 'v1.0.6'
    git push origin main --follow-tags
    
  5. Watch the pipeline in GitLab → Build → Pipelines. On success the release is live on both indexes:
    pip install computational_stopwatch==1.0.6
    conda install -c <your-anaconda-channel> computational_stopwatch=1.0.6
    

What the pipeline does

The v* tag triggers .gitlab-ci.yml, which runs three stages:

Stage Job What it does
verify verify tag Refuses the release unless the tag matches __version__, the tagged commit is an ancestor of main, and HISTORY.md has the matching section
build build sdist and wheel python -m build plus twine check
release publish to pypi Uploads dist/* to PyPI
release publish to anaconda conda build conda-recipe and uploads the noarch package to anaconda.org

If verify tag fails, nothing is uploaded anywhere — fix the mismatch, delete the tag (git tag -d v1.0.6 && git push origin :refs/tags/v1.0.6), and tag again.

Required CI/CD variables

Set these in GitLab → Settings → CI/CD → Variables, all Masked and Protected. No secret belongs in the repository.

Variable Value
PYPI_API_TOKEN PyPI API token, including the pypi- prefix
ANACONDA_API_TOKEN anaconda.org token with allow write permission
ANACONDA_USER anaconda.org user or organisation to upload into

Because the variables are Protected, add v* under Settings → Repository → Protected tags, otherwise the release jobs cannot see them.

Running the tests

The suite is developer-only and is not part of any published package.

pip install -e . pytest
pytest

It runs in the verify stage of the pipeline on every branch, merge request and tag, and a tagged release will not publish unless it is green.

Building locally

python -m build                             # dist/*.whl, dist/*.tar.gz
conda build conda-recipe -c conda-forge     # noarch conda package

Versions History

v1.0.8

  • package version (pip and conda) is now derived directly from the git tag via setuptools_scm, instead of a hardcoded __version__

v1.0.5

  • minor fix

v1.0.4

  • added HISTORY.md in the pip package for compatibility with the conda packaging

v1.0.3

  • added __str__ function to easily include just the time stamp inside other strings

v1.0.2

  • updated the README
  • added multiple streams functionality

v1.0.1

  • minor fixes

v1.0.0

  • first reelease

Release files for computational-stopwatch 1.0.8

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

Source distribution (sdist)

Source distribution for computational-stopwatch 1.0.8
File Size Uploaded
computational_stopwatch-1.0.8.tar.gz 8.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for computational-stopwatch 1.0.8
File Interpreter ABI Platform
computational_stopwatch-1.0.8-py3-none-any.whl Python 3 none any Details

Total release size: 14.9 kB

Release files / computational_stopwatch-1.0.8.tar.gz

Download URL computational_stopwatch-1.0.8.tar.gz
Size 8.6 kB
Tags Source
SHA-256 checksum
How to use checksums
7893622ddbf02b3ef7717b3383414b77403d67fb640e873ea8c7c193bd989e1b
BLAKE2b-256 checksum
How to use checksums
4833b3b40003c5aeb2fe479ca1f4032c2c44697010cfe5775f874043957fca02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / computational_stopwatch-1.0.8-py3-none-any.whl

Download URL computational_stopwatch-1.0.8-py3-none-any.whl
Size 6.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc9b17f1f5e2e7b09543010eb5e1e3b83127f72abd560a49bd0fd0bbe4fd2bef
BLAKE2b-256 checksum
How to use checksums
c0f29874d19ba0648262d258fb74f2a1d43a91c502cfde94eb5076a6472882d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

This release

1.0.8 This release

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

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